將文件中的字元串替換為另一個都保存在變數中的字元串
我想用另一個字元串替換文件中找到的字元串,但兩者都有一個特殊字元(在本例中是一個
.
字元),例如1.0
和2.0
.所以這是目前使用的命令:
sed -i 's/1\.0/2\.0/g' /home/user1/file1.txt
如果
1.0
和2.0
被保存在變數$i
和中$j
怎麼辦?哪裡i
有價值1.0
,哪裡j
有價值2.0
,我還能i
用什麼來代替j
?
您可以使用
sed
為您進行修復:printf '%s\n' "$i" "$j" | sed 's/[]\$*&/.^[]/\\&/g;H;$!d x;y|\n|/|;s|.*|s&/g|' | sed -f - /path/to/infile
所以這個
s///
替換將轉義輸入中的任何/所有 BRE 元字元:s/[]\$*&/.^[]/\\&/g
…通過在每個前面加上反斜杠。然後第
sed
一個將第一行的副本保存$i
在H
舊空間中,方法是在其前面添加一個\n
ewline 字元。然後刪除該$i
行,d
因為它!
不是$
最後一行。下一行 -$j
行 - 也是最後一行,在得到與第一行相同的處理後,它不會d
被刪除。相反,它x
會更改保持和模式緩衝區並對連接的結果進行操作。此時模式空間看起來像:\n1\.0\n2\.0
…所以我們
y///
將所有ewlines轉換\n
為/
斜線,將所有模式空間替換為自身加上一個前置和一個附加,這讓我們:s///``.*``&``s``/g
s/1\.0/2\.0/g
然後將其自動列印到第二個
sed
讀取 stdin - 或-f -
- 作為其腳本的內容。當第一個sed
完成並關閉它們之間的管道時,第二個sed
開始應用……s/1\.0/2\.0/g
…到其命名輸入文件中的每一行 - 在這裡
/path/to/infile
。我這樣寫你的文件:
printf '%04s%04s%04s%04s\n' \ 0 0 -1 0 1 0 0 0 0 -1\ 0 0 1.5 2.0 1.0 0 >/tmp/temp
這給了我一個像…
0 0 -1 0 1 0 0 0 0 -1 0 0 1.5 2.0 1.0 0
然後我寫了一個不同版本的腳本,比如:
ii=0.0 for i in 1.0 2.0 3.0 4.0 do str2=$i printf '\033[41m## %s \033[0m\n' \ "str2 = $str2" "$ii $str2" printf %s\\n "$ii" "$str2" ii=$str2 done | sed ' s/[]\$^&*./[]/\\&/g;H;x s|^\(\n\)\(.*\)\n\(.*\)\n\(.*\)\n\(.*\)|\ bs\5\1:i\5\1i\\\1\2\\\1\3\1:s\5\1s/\4/\5/gp;ti\5|p s|||;h;d' | sed -f - /tmp/temp
它僅使用 shell 生成字元串,但允許
sed
進行所有數據處理。請注意,儘管呼叫了兩個sed
s,但每個只呼叫一次。當我執行它時,結果是:
0 0 -1 0 1 0 0 0 0 -1 0 0 1.5 2.0 2.0 0 ## str2 = 2.0 ## 1.0 2.0 1.5 3.0 3.0 0 ## str2 = 3.0 ## 2.0 3.0 1.5 4.0 4.0 0 ## str2 = 4.0 ## 3.0 4.0 1.5 4.0 4.0 0
以我希望你的意思開始的行
#
是紅色的。僅在替換成功sed
時才寫入它們。s///
第一個為第二個編寫的腳本sed
如下所示:bs1\.0 :i1\.0 i\ [41m## str2 = 1\.0 [0m\ [41m## 0\.0 1\.0 [0m :s1\.0 s/0\.0/1\.0/gp;ti1\.0 bs2\.0 :i2\.0 i\ [41m## str2 = 2\.0 [0m\ [41m## 1\.0 2\.0 [0m :s2\.0 s/1\.0/2\.0/gp;ti2\.0 bs3\.0 :i3\.0 i\ [41m## str2 = 3\.0 [0m\ [41m## 2\.0 3\.0 [0m :s3\.0 s/2\.0/3\.0/gp;ti3\.0 bs4\.0 :i4\.0 i\ [41m## str2 = 4\.0 [0m\ [41m## 3\.0 4\.0 [0m :s4\.0 s/3\.0/4\.0/gp;ti4\.0
請注意,儘管看起來
[
字元串沒有被轉義,但這只是我的終端對輸出的影響——它最終會立即吃掉 char\033
。當第二個sed
接收到腳本時,輸入就像\033\[...
但是它i
插入到標準輸出的輸出是\033[...