Linux

如何僅使用 sed 在第 N 次出現文本之前添加文本?

  • January 21, 2022

我搜尋了以前的問題,但它們只是在發生後添加了這樣的內容。我需要它在之前:

world world
world world
world world

因此 sed 必須添加“hello”,例如在特定文本第 N 次出現的開頭。在這種情況下,我將它添加到第四世界:

world world
world hello world
world world

sed是這項工作的錯誤工具。使用awkperl代替。例如

$ perl -pe 's/world/++$i == 4 ? "hello world" : $&/ge' input.txt 
world world
world hello world
world world

請注意,這使用了/eperl 正則表達式修飾符,它導致替換s///運算符的替換部分作為 perl 程式碼執行,而不是被解釋為字元串。

該程式碼在每次匹配時++$i == 4 ? "hello world" : $&預先增加一個計數器變數 ( $i),如果它等於 4,則將匹配替換為“hello world”,否則將匹配替換為自身 ( $&)。

我知道你說“使用 sed”,但如果你不得不在現實世界中做這樣的事情,這裡是如何在每個 Unix 機器上的任何 shell 中使用任何 awk 並進行全字字元串比較(參見how-do-i -find-the-text-that-matches-a-pattern了解為什麼這很重要):

$ awk -v n=4 '{
   for (i=1;i<=NF;i++) {
       if ( ($i == "world") && (++cnt == n) ) {
           $i = "hello " $i
       }
   }
   print
}' file
world world
world hello world
world world

想像一下您的輸入是:

$ cat file
google.com mygoole.comedy
googleycom google.com
google.com google.com

你想把“你好”放在第四個之前google.com(現在是輸入中的最後一個)。使用上面的 awk 腳本,您只需更改$i=="world"$i=="google.com"

$ cat file
awk -v n=4 '{
   for (i=1;i<=NF;i++) {
       if ( ($i == "google.com") && (++cnt == n) ) {
           $i = "hello " $i
       }
   }
   print
}' file
google.com mygoole.comedy
googleycom google.com
google.com hello google.com

現在嘗試對 sed 腳本做同樣的事情(特別是如果您只使用 POSIX 語法而沒有 GNU 擴展)。現在嘗試將in&out其用作替換文本hello,您會發現 sed 腳本存在更多問題。

引用自:https://unix.stackexchange.com/questions/686576