Text-Processing

根據字元串列表和相應替換列表替換文件中的字元串

  • September 17, 2021

我正在嘗試替換 a 中的字元串file A

Hello Peter, how is your dad? where is mom? 

要替換的字元串在哪裡file B

Peter
dad
mom

並且它們相應的替換在file C

John
wife
grandpa

預期結果:

Hello John, how is your wife? where is grandpa?

我可以編輯,通過使用相應行中的值file A替換中的值嗎?file B``file C

到目前為止我做了什麼:

cat 1.txt | sed -e "s/$(sed 's:/:\\/:g' 2.txt)/$(sed 's:/:\\/:g' 3.txt)/" > 4.txt

如果file B&中只有file C一行,它可以工作,如果有多行,它將不起作用。

最簡單的方法sed是處理這兩個列表並將它們轉換為*腳本文件,*例如

s/line1-from-fileB/line1-from-fileC/g
s/line2-from-fileB/line2-from-fileC/g
....................................
s/lineN-from-fileB/lineN-from-fileC/g

然後將sed執行,編輯fileA. 正確的方法是先處理LHS/RHS並轉義可能出現在這些行上的任何特殊字元,然後加入LHSRHS添加s、分隔符/g(例如 with paste)並將結果通過管道傳輸到sed

paste -ds///g /dev/null /dev/null \
<(sed 's|[[\.*^$/]|\\&|g' fileB) <(sed 's|[\&/]|\\&|g' fileC) \
/dev/null /dev/null | sed -f - fileA

就是這樣:一個paste和三個seds 將只處理每個文件一次,而不管行數如何。

這假設您的 shell 支持程序替換,並且您可以從stdinsed讀取腳本文件。此外,它不會就地編輯(我省略了開關,因為所有s 都不支持它)-i``sed

如果您希望替換彼此獨立完成,例如:

foo -> bar
bar -> foo

應用於

foobar

以導致:

barfoo

foofoo天真的s/foo/bar/g; s/bar/foo/g翻譯相反,您可以這樣做:

perl -pe '
 BEGIN{
   open STRINGS, "<", shift@ARGV or die"STRINGS: $!";
   open REPLACEMENTS, "<", shift@ARGV or die "REPLACEMENTS: $!";
   while (defined($a=<STRINGS>) and defined($b=<REPLACEMENTS>)) {
     chomp ($a, $b);
     push @repl, $b;
     push @re, "$a(?{\$repl=\$repl[" . $i++. "]})"
   }
   eval q($re = qr{) . join("|", @re) . "}";
 }
 s/$re/$repl/g' strings.txt replacements.txt fileA 

這是perl預期的正則表達式patterns.txt。由於 perl 正則表達式可以執行任意程式碼,因此對它們進行清理很重要。如果只想替換固定字元串,可以將其更改為:

perl -pe '
 BEGIN{
   open PATTERNS, "<", shift@ARGV or die"PATTERNS: $!";
   open REPLACEMENTS, "<", shift@ARGV or die "REPLACEMENTS: $!";
   for ($i = 0; defined($a=<PATTERNS>) and defined($b=<REPLACEMENTS>); $i++) {
     chomp ($a, $b);
     push @string, $a;
     push @repl, $b;
     push @re, "\\Q\$string[$i]\\E(?{\$repl=\$repl[$i]})"
   }
   eval q($re = qr{) . join("|", @re) . "}";
 }
 s/$re/$repl/g' patterns.txt replacements.txt fileA 

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