![當替換命令寫入檔案時,sed 僅替換檔案的偶數行](https://rvso.com/image/1416716/%E7%95%B6%E6%9B%BF%E6%8F%9B%E5%91%BD%E4%BB%A4%E5%AF%AB%E5%85%A5%E6%AA%94%E6%A1%88%E6%99%82%EF%BC%8Csed%20%E5%83%85%E6%9B%BF%E6%8F%9B%E6%AA%94%E6%A1%88%E7%9A%84%E5%81%B6%E6%95%B8%E8%A1%8C.png)
我將所有替換命令都放在一個檔案中(例如replace.sed),並將其與sed 的-f 標誌一起使用(sed -f Replace.sed InputFile)。但現在我遇到了一種情況,我需要僅在給定輸入檔案的偶數行上應用這些替換規則(即僅在第 2,4,6 行等)。文件也被其他腳本使用。
答案1
使用進程替換來sed
動態調整檔案中的命令:
$ cat replace.sed
s#foo#bar#
。
$ printf "foo\nfoo\nfoo\nfoo\n" | sed -f replace.sed
bar
bar
bar
bar
。
$ printf "foo\nfoo\nfoo\nfoo\n" | sed -f <(sed 's#^#2~2#g' replace.sed)
foo
bar
foo
bar
答案2
sed -f <(sed -e 's/.*/2~2{&;}/' replace.sed) InputFile
答案3
其他答案試圖告訴您的是使用sed
的地址形式:first~step
地址
… 支援以下地址類型: …
第一的~步匹配每一個步'以 line 開頭的行第一的。例如,「
sed -n 1~2p
」將列印輸入流中的所有奇數行,位址「2~5
」將從第二行開始符合每五行。 第一的可以為零;在這種情況下,sed
操作就好像它等於 步。 (這是一個擴展。)
顯而易見的解決方案是在每個命令之前加上replace.sed
with 2~2
(或者0~2
,如果它在您的版本中工作sed
),以使命令在每隔一行上運行,從第二行開始(即輸入流中的所有偶數行,按照您的要求)。但你說你不能修改replace.sed
。好吧,下一步(如其他答案所確定的,但沒有解釋)是使用 shell 的流程替代功能,其行為就像一個文件,是.如果,正如您的問題所示, 只是一系列簡單的替代命令,那麼
<(command_list)
command_list
replace.sed
sed -f <(sed 's/^/2~2/g' replace.sed)
應該管用。
但這有缺點:
- 如果每行有多個命令,則上述內容只會影響每行的第一個命令。
- 如果您有帶有數字地址的命令(例如,
42s/Zaphod/Beeblebrox/
),它們將被轉換為,例如,轉換為2~242…
,結果顯而易見。 - 如果您的命令帶有非數位位址(例如,
/windows/s/command/cmd/
),則上述命令將徹底失敗。
如果出現任何這些情況,您應該使用
sed -f <(sed -e 's/.*/2~2{&;}/' replace.sed)
將sed
每行上的所有命令放入一個命令組的變體。
replace.sed
但如果有多行命令,即使這樣也會失敗。
基於上述想法,我想出了
sed -f <(echo '0~2{'; cat replace.sed; echo '}')
這使得全部的 replace.sed
文件到命令組。在我的表面測試中,這似乎解決了我對其他解決方案提出的擔憂。如果它有一個很長replace.sed
或非常複雜的命令的問題,我不會感到震驚。