linux中sed中用s 替換中遇到的問題


sed替換時候不能用-n,只輸出替換的行,為什么????

比如:

sed "2,4s/\"//g" /var/lib/status     #可以輸出

但是:

sed -n "2,4s/\"//g" /var/lib/status #什么也數不出來了

 

 

問題:文件helloword,sh

root@ubuntu:/home/dyx/linux 17:25:36 188# nl -b a helloword.sh
     1    #!/bin/bash
     2    echo "helloword!";
     3    echo "The first parameter:" $1;
     4    echo "The second parameter:" $2;
     5    echo "The whole parameter is:" $@
     6    
     7    
     8    
     9    echo 'insert-------------------------------';
    10    echo '$0: '$0;
    11    echo '$*: '$*;
    12    echo '$@: '$@;
    13    echo '$#: '$#;
    14    echo '$!: '$!;
    15    echo '$?: '$?;
    16    echo '$$: '$$;

想把9到最后的行中單引號變為上引號;

用命令:

1 :sed '9,$s/\'/\"/g' helloword.sh

一直出現換行符號,不知道為什么,最后查了網上資料,說sed中用s替換最好用雙引號“

於是查到:

1 sed "s/'/\"/g"

可以替換全部的,

之后用

1 sed "9,$s/'/\"/g"

就不可以了

1 root@ubuntu:/home/dyx/linux 17:32:18 189# sed "9,$s/'/\"/g"
2 sed: -e 表達式 #1, 字符 6: 未知的命令:“"”↵

發現需要在9和$之間留個空格,

 1 root@ubuntu:/home/dyx/linux 17:33:33 191# sed "9,$ s/'/\"/g" helloword.sh
 2 #!/bin/bash
 3 echo "helloword!";
 4 echo "The first parameter:" $1;
 5 echo "The second parameter:" $2;
 6 echo "The whole parameter is:" $@
 7 
 8 
 9 
10 echo "insert-------------------------------";
11 echo "$0: "$0;
12 echo "$*: "$*;
13 echo "$@: "$@;
14 echo "$#: "$#;
15 echo "$!: "$!;
16 echo "$?: "$?;
17 echo "$$: "$$;
 1 root@ubuntu:/home/dyx/linux 19:47:53 201# sed "8,$ s/\'/\"/g" helloword.sh
 2 #!/bin/bash
 3 echo "helloword!";
 4 echo "The first parameter:" $1;
 5 echo "The second parameter:" $2;
 6 echo "The whole parameter is:" $@
 7 
 8 
 9 "
10 echo 'insert-------------------------------';"
11 echo '$0: '$0;"
12 echo '$*: '$*;"
13 echo '$@: '$@;"
14 echo '$#: '$#;"
15 echo '$!: '$!;"
16 echo '$?: '$?;"
17 echo '$$: '$$;"

所以只有

1 sed "8,$ s/'/\"/g" helloword.sh

正確!

不太理解!

當用腳本時:

1  cat ss.sed
2 '6,$ s/'/"/g'
1 sed -f ss.sed helloword.sh

報錯:

sed:文件 ss.sed 行號:1:未知的命令:“'
sed -e "s/^'//g" -e  "s/'$//g" ss.sed
6,$ s/'/"/g

這樣就可以了。

但是

sed -e "/^'/d" -e  "/'$/d" ss.sed

沒反應?????

 看過參考之后,發現sed中d是對整個行起作用的,所以就把那一行刪掉了,當然沒反應了啊

 

cat sssss.sed
s#/#\#g
 sed "s/\\\\/\\\\\\\\/g" sssss.sed 
s#/#\\#g

不知道你領悟沒呢,其實在命令行中用sed的s代替,要轉義兩次,一次是終端的轉義,一次是sed本身的轉義;

 

參考一:

Sed使用的變量里含有轉義字符的解決

 

最近寫腳本的時候碰到了這方面的問題,到網上搜了半天也沒找到好一點的方案或總結。今天我把自己的摸索寫一下。

 

首先是Sed里使用變量的問題

網上有人總結了四種方案:

1.       eval sed 's/$a/$b/' filename

2.       sed "s/$a/$b/" filename

3.       .sed 's/'$a'/'$b'/' filename

4.       .sed s/$a/$b/ filename

我比較喜歡第二種,也就是:Sed后面的表達式一般用單引號引起來('),當需要使用變量時就換用雙引號(")。

關於單雙引號的區別:

單引號:shell處理命令時,對其中的內容不做任何處理。即此時是引號內的內容是sed命令所定義的格式。

雙引號:shell處理命令時,要對其中的內容進行算術擴展。如果想讓shell擴展后得到sed命令所要的格式,使用命令:sed -n "/\\\\$/p" haha,擴展后得到的結果即\\$.

 

因此對於語句類似:

$Comfilename="/home/evan/sandbox/Main/"

1. echo $Comfilename | sed 's#\/#\\\/#g'

2. echo $Comfilename | sed "s#\/#\\\/#g"

第一個的結果是:\/home\/evan\/sandbox\/Main\/

而第二個還是:/home/evan/sandbox/Main/ 因為雙引號會將“\/“解釋為”/“,所以sed "s#\/#\\\/#g"Shell解釋成了sed s#/#\/#g sed里執行時又把”\/“轉義為”/“了,這樣相當於進行了了兩次解釋,就得不到想要的結果了。

這個例子告訴我當沒必要用雙引號的的時候就不要用,要不然說不定什么時候你就會很郁悶。Sed使用的變量里含有轉義字符的解決當然單引號效率要比雙引號高也是不要濫用雙引號的原因之一。

 

言歸正傳,如何在sed的變量里使用那些特殊的需要轉義的字符呢?

網上提出的一種方法是將sed里表示替換用的s后面的表示分隔用的字符換成別的變量里沒有的字符這樣就相當於變量里沒有要轉義的字符了。

如:

sed –i "s# $Comfilename#/Root/#" filename.list

這是一個好辦法。但很不幸我需要的是刪除“d”不是替換“s“。當我把同樣的方法用於刪除時似乎沒有起到作用:sed –i "# $Comfilename#d" filename.list

 

於是只能自己手工先改寫變量

$Comfilename="/home/evan/sandbox/Main/"

Tempname=` echo $Comfilename | sed 's#\/#\\\/#g'`  (這里把反單引號執行的結果給臨時變量,同樣的方法可以改寫其他需要轉義的符號。)

sed –i "# $ Tempname #d" filename.list

 

個人感覺這種方法不是很好,但在網上找了半天也沒找到更好的方法,只能感嘆SHELL的博大精深,吾輩還得慢慢求索。Sed使用的變量里含有轉義字符的解決

 

參考二:

在使用sed對日志或者其它文本進行parse的過程當中,有時候我們需要引用外部變量的值,

或者獲取一個shell命令執行的結果,以便達到更加可觀的輸出結果。這里介紹如何做到。

sed中使用變量替換

1.sed命令使用雙引號的情況下,使用$var直接引用

$ echo|sed "s/^/$RANDOM.rmvb_/g"
29328.rmvb_

# 上面例子引用了一個環境變量$RANDOM的值

2.sed命令使用單引號的情況下,使用'"$var"'引用

類似,我們可以看到

$ echo|sed 's/^/'"$RANDOM"'.rmvb_/g'
31338.rmvb_

sed中執行外部命令

1.sed命令使用單引號的情況下使用'`shell command`'或者'$(shell command)'引用命令執行的結果

還是以上面案例分析,例子如下

$ echo|sed 's/^/'`echo $RANDOM`'.rmvb_/g'
8063.rmvb_

# 上面的例子使用了舊式的命令替換,也可以采用新式的命令替換方法,如下

$ echo|sed 's/^/'$(echo $RANDOM)'.rmvb_/g'
18554.rmvb_

# 下面例子取用當前日期作為結果的一部分,如下

$ echo|sed 's/^/'$(date +"%Y%m%d")'.rmvb_/g'
20120108.rmvb_

2.sed命令使用雙引號的情況下直接`shell command`或者$(shell command)引用命令執行的結果

類似的,雙引號的情況,如下

$ echo|sed "s/^/$(date +"%Y%m%d").rmvb_/g"
20120108.rmvb_

# 使用環境變量$RANDOM以及舊式命令替換的例子

$ echo|sed "s/^/`echo $RANDOM`.rmvb_/g"
4988.rmvb_

總結

在sed語句里面,變量替換或者執行shell命令,雙引號比單引號少繞一些彎子


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM