複数行文字列を手動エスケープなしで複数行文字列に置き換える

複数行文字列を手動エスケープなしで複数行文字列に置き換える

テキストファイルがあり、に含まれる(複数行)文字列をに含まれている他の文字列に置き換えたいとしますtext.txt。どうすればいいですか? (私は正規表現を使用したくありません。実際には、に含まれる文字列をに含まれているテキストに置き換えたいと思います。before.txtafter.txtbefore.txtafter.txttext.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

、しかし、まだ動作しません。以前の文字列が文字列を置き換える行全体と正確に一致していることを確認して、1つのインスタンスで機能するようにしました。しかし、行の先頭にない文字列を置き換えるのと同じようには機能しません。例:text.txtファイルには以下が含まれます:

Here is 
some text.

before.txt含む:text

after.txt含む:whatever

機会なし。

ベストアンサー1

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

ここでは一重引用符の中にバックティックがあるので、シェルはこれを処理しませんが、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式で処理されるようにします(これは、シェルがファイルの内容をPerlコマンドラインに拡張できるようにする場合にのみ実際に重要です)。


後者の例には、通常どおり改行文字を表すsome text.\nintext.txtおよびtext\nin があります。ファイルがPerlにロードされるとそのままインポートされるため、最後の改行文字も重要です。他のファイルには改行の前にドットがあり、他のファイルにはドットがないため、一致しません。before.txt\nbefore.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.

おすすめ記事