テキストファイル()がありますdevel.xml
。
temp.txt
文字列を別のファイル()の内容に置き換えるために、REPLACETHISという単語を追加しました。
私が得た最も近いものは次のとおりです。
sed -i -e "/REPLACETHIS/r temp.TXT" -e "s///" devel.txt;
文字列の後に内容を挿入してから文字列を削除します。
これが最善の方法ですか?
答え1
ファイルに表示されるすべての場所を削除しSUBSTITUTETHIS
(残りの行は削除しません)、その行のtemp.TXT
下にコンテンツを挿入するだけです。 1行に複数回発生すると、最初のSUBSTITUTETHIS
発生のみが削除され、1つのコピーのみが追加さtemp.TXT
れます。
発生時に行全体を置き換えるには、SUBSTITUTETHIS
このd
コマンドを使用します。両方を同時に実行する必要があるため、一致するものがあればr
サポートd
グループに入れてください。
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
またはパールを使用してください。これは短いですが、cat
交換ごとに一度実行されます。
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
答え2
sed 's/<\!--insert \(.*\.html\) content here-->/&/;s//\ncat "\1"/e'
または、@KlaxSmashingを使用すると、よりクリーンで(私の考えでは)、より効果的な改善があるかもしれません。
sed 's/<\!--insert \(.*\.html\) content here-->/\ncat "\1"/e'
これは、HTML部分を別のHTMLファイルに挿入するために私が作成した1行のテンプレートシステムです。パターンでファイル名を指定できます。その後、パターンはパターンで指定されたファイル名の内容に置き換えられます。
たとえば、行<!--insert somehtmlfile.html content here-->
ですsomehtmlfile.html
。&
などの文字を特に処理しなくてもうまく動作するようです\
。
$ cat first.html
first line of first.html
second line of first.html
$ cat second.html
this is second.html
\ slashes /
and ampersand &
and ! exclamation point
end content from second.html
$ cat file\ name\ space.html
the file containing this content has spaces in the name
and it still works with no escaping.
$ cat input
<!--insert first.html content here-->
input line 1
<!--insert first.html content here-->
input line 2
<!--insert second.html content here-->
input line 3
<!--insert file name space.html content here-->
$ sed 's/<\!--insert \(.*\.html\) content here-->/&/;s//\ncat "\1"/e' input
first line of first.html
second line of first.html
input line 1
first line of first.html
second line of first.html
input line 2
this is second.html
\ slashes /
and ampersand &
and ! exclamation point
end content from second.html
input line 3
the file containing this content has spaces in the name
and it still works with no escaping.
$
答え3
使用幸せ(以前のPerl_6)
~$ raku -pe 'BEGIN my $donor_file = "donor_file.txt".IO.slurp; \
s:g/REPLACETHIS/{$donor_file}/;' recipient_file.txt
このRakuの答えは、おなじみのs///
代替イディオムを使用し、-pe
自動印刷(sedに似た)フラグを使用します。
最初のステートメントでは、donor_file.txt
ed slurp
(一度にすべて読み取り)を$donor_file
変数に入れます。 2番目の文では、:g
副詞は私たちに代替をs///
実行するように指示します。:global
代替演算子(半置換)の右側の中かっこで$donor_file
変数を囲むと、補間がトリガされ、目的の{…}
テキストが挿入されます。