テキストファイルがあり、に含まれる(複数行)文字列をに含まれている他の文字列に置き換えたいとしますtext.txt
。どうすればいいですか? (私は正規表現を使用したくありません。実際には、に含まれる文字列をに含まれているテキストに置き換えたいと思います。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
、しかし、まだ動作しません。以前の文字列が文字列を置き換える行全体と正確に一致していることを確認して、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.\n
intext.txt
およびtext\n
in があります。ファイルがPerlにロードされるとそのままインポートされるため、最後の改行文字も重要です。他のファイルには改行の前にドットがあり、他のファイルにはドットがないため、一致しません。before.txt
\n
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.
答え2
一重引用符内の逆引用符は文字通り処理されます。提供された例では、これを二重引用符で置き換えることができるはずです。
バックティックも何らかの理由で望ましくないので、ここでは次のように変更しました。$( )
perl -i -p0e "s/$(cat before.txt)/$(cat after.txt)/se" text.txt
注:私はあなたの引用問題を解決するだけであり、あなたの命令があなたの意図を達成するという保証はありません。