web-dev-qa-db-ja.com

ファイル内のパターンを他のファイルの内容で置き換える

テキストファイル(devel.xml)があります。

この文字列を別のファイル(temp.txt)内のコンテンツで置き換えるために、Word REPLACETHISを追加しました。

私が持っている最も近いものはこれです:

sed -i -e "/REPLACETHIS/r temp.TXT" -e "s///" devel.txt;

これにより、文字列の後にコンテンツが挿入され、その後で文字列が削除されます。

これはそれを行うための最良の方法ですか?

20
RafaelGP

SUBSTITUTETHISをファイル内のどこにでも削除し(それが出現する行の残りの部分は削除しない)、その行の下にtemp.TXTの内容を挿入します。 SUBSTITUTETHISが1行に複数回出現する場合、最初の出現のみが削除され、temp.TXTのコピーが1つだけ追加されます。

SUBSTITUTETHISが表示されたときに行全体を置き換える場合は、dコマンドを使用します。一致する場合はrdの両方を実行する必要があるため、括弧で囲んだグループに入れます。

sed -e '/SUBSTITUTETHIS/ {' -e 'r temp.TXT' -e 'd' -e '}' -i devel.txt

一部のsed実装では、セミコロンを使用してコマンドを区切り、中かっこで完全に区切り文字を省略できますが、rコマンドへの引数を終了するには改行が必要です。

sed -e '/SUBSTITUTETHIS/ {r temp.TXT
                          d}' -i devel.txt

SUBSTITUTETHISをファイルの内容で置き換えたいが、行の前後にあるものは保持したい場合は、さらに複雑になります。最も簡単な方法は、sedコマンドにファイルの内容を含めることです。その内容を適切に引用する必要があることに注意してください。

sed -e "s/SUBSTITUTETHIS/$(<temp.TXT sed -e 's/[\&/]/\\&/g' -e 's/$/\\n/' | tr -d '\n')/g" -i devel.txt

または、Perlを使用します。これは短いですが、置換ごとにcatを1回実行します。

Perl -pe 's/SUBSTITUTETHIS/`cat temp.TXT`/ge' -i devel.txt

スクリプトの開始時に一度ファイルを読み取り、シェルコマンドに依存しないようにするには:

Perl -MFile::Slurp -pe 'BEGIN {$r = read_file("temp.TXT"); chomp($r)}
                        s/SUBSTITUTETHIS/$r/ge' -i devel.txt

(読みやすくするために2行で表示されていますが、改行は省略できます)。ファイル名が変数の場合、引用の問題を回避するために、環境変数を介してスクリプトに渡します。

replacement_file=temp.TXT Perl -MFile::Slurp -pe 'BEGIN {$r = read_file($replacement_file); chomp($r)}
                        s/SUBSTITUTETHIS/$r/ge' -i devel.txt