Perl

用多行字元串替換多行字元串,無需手動轉義

  • December 9, 2019

假設我有一個文本文件,我想用另一個text.txt包含在 中的字元串替換包含在中的(多行)字元串,我該怎麼做?(我不想使用正則表達式,我真的想用 in 中包含的文本替換 in 中包含的字元串。before.txt``after.txt``before.txt``after.txt``text.txt

我希望使用以下建議的方法: https ://unix.stackexchange.com/a/26289/288916

我試過:

perl -i -p0e 's/`cat before.txt`/`cat after.txt`/se' text.txt

但是,除非我是一個徹頭徹尾的白痴並且把一些瑣碎的事情搞砸了,否則我不能簡單地將它擴展到載入一個字元串,以便從帶有 cat 的文件中找到。

逃跑可能出了點問題。該文件before.txt包含諸如/[]".


謝謝@ilkkachu,我試過了:

perl -i -0 -pe '$b = `cat before.txt`; $a = `cat after.txt`; s/\Q$b\E/$a/s\' text.txt

,但它仍然無法正常工作。通過確保之前的字元串與要替換字元串的整行完全匹配,我讓它在一個實例中工作。但它不起作用,例如替換在行首找不到的字元串。範例:text.txt文件包含:

Here is 
some text.

before.txt包含:text

after.txt包含:whatever

沒有機會。

perl -i -p0e 's/`cat before.txt`/`cat after.txt`/se' text.txt

在這裡,單引號內有反引號,因此它們不被 shell 處理,但 Perl 將它們視為原樣。再說一次,Perl支持反引號作為一種引用形式,但它在內部不起作用s///

只要您在 Perl 命令行上使用-0或,多行模式不是問題。-0777-0將用 NUL 字元分隔行,文本文件沒有,並且-0777會一口氣讀取整個文件。)

您可以使用雙引號來執行此操作,但這會直接在 Perl 腳本中擴展文件的內容,並且任何特殊字元都將被視為腳本的一部分。一個斜杠會結束s///運算符並導致問題。

相反,讓 Perl 讀取文件:

perl -i -0 -pe '$b = `cat before.txt`; $a = `cat after.txt`; s/$b/$a/s' text.txt

在這裡,內容before.txt仍將被視為正則表達式。如果你想阻止它,請s/\Q$b\E/$a/s改用。

我不認為你想要這個e標誌s///,它會使替換被當作 Perl 表達式(如果你讓 shell 將文件內容擴展到 Perl 命令行,這同樣很重要)。


在您後面的範例中,您有some text.\nintext.txttext\nin before.txt,其中\n像往常一樣代表換行符。當文件在 Perl 中載入時,它們按原樣獲取,因此最後的換行符很before.txt重要。另一個文件在換行符之前有一個點,另一個沒有,所以它們不匹配。

chomp $b;您可以在載入文件後刪除可能的尾隨換行符。您可以使案例如刪除可能的尾隨換行符$b =~ s/\n$//;

$ perl -0 -pe '$b = `cat before.txt`; $a = `cat after.txt`; $b =~ s/\n$//; $a =~ s/\n$//; s/$b/$a/s' text.txt
Here is 
some whatever.

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