grepを使って正しい行を見つけ、sedを使って内容を変更してから元のファイルに戻しますか?

grepを使って正しい行を見つけ、sedを使って内容を変更してから元のファイルに戻しますか?

ファイルの特定の行にある単一の単語を変更しようとしていますが、すべての単語を連結するのに問題があります。

デフォルトでは、私のファイルの1行には "firmware_revision"というキーワードがあり、この行(およびこの行のみ)の "test"という単語を "production"という単語に置き換えたいと思います。

だから私はこれを行うことができます:

grep 'firmware_revision' myfile.py | sed 's/test/production'

これにより、必要な行を選択して置換を実行できますが、古い行を置き換えるためにこの新しい行を元のファイルに配置する方法がわかりません。明らかにファイルにリダイレクトすることはできません。それではどうすればいいですか?

一時ファイルを使用してもgrep必要な行を取得するには、ファイル内の他のすべてのデータが失われるため、すべてのデータを一時ファイルにリダイレクトし、元のファイルを一時ファイルに置き換えることはできません。

編集 - 誰かが追加情報を要求しました。

次のような行でいっぱいのファイルがあるとしましょう。

[
  ('key_name1', str, 'value1', 'Description'),
  ('key_name2', str, 'value2', 'Description'),
  ('key_name3', str, 'value3', 'Description'),
  ('firmware_revision', str, 'my-firmware-name-test', 'Firmware revision name')
]

ここで、「firmware_revision」を含む行を探して、その行の「test」という単語のすべてのインスタンスを「production」に変更するスクリプト(可能な行)を作成したいと思います。 「test」という単語がファイル内の他の場所にある可能性があり、その場所を変更したくありません。明確にするために、上記の行を次のように変更したいと思います。

('firmware_revision', str, 'my-firmware-name-production', 'Firmware revision name')

どうすればいいですか?

答え1

努力する:

sed -i.bak '/firmware_revision/ s/test/production/' myfile.py

ここでは/firmware_revision/条件として機能します。正規表現に一致するジョブの場合は true firmware_revision、その他のジョブの場合は false です。条件が true の場合、次のコマンドが実行されます。この場合、コマンドはの最初の発生をに置き換える代替コマンドtestですproduction

つまり、コマンドはs/test/production/regexと一致する行でのみ実行されますfirmware_revision。他のすべての行は変更されません。

デフォルトでは、sed は出力を標準出力に送信します。しかし、ファイルをその場で変更しようとしています。だからこの-iオプションを追加しました。特に、-i.bakファイルを変更し、拡張子を.bak

このコマンドが自分に適していると判断し、バックアップを作成せずに危険にさらしたい場合は、GNU sed(Linux)を使用して以下を使用してください。

sed -i '/firmware_revision/ s/test/production/' myfile.py

対照的に、BSD(OSX)ではこの-iオプションに引数が必要です。バックアップを維持したくない場合は、空の引数を指定してください。したがって、以下を使用してください。

sed -i '' '/firmware_revision/ s/test/production/' myfile.py

編集する

質問編集でOPが聞いたすべて表示されるtest内容を変更してくださいproduction。この場合、g代替コマンドにオプションを追加します。グローバル(この行の場合)交換:

sed -i.bak '/firmware_revision/ s/test/production/g' myfile.py

答え2

sedオプションをサポートしていない古いシステムの場合-i:

TF=$( mktemp -t "${0##*/}"_$$_XXXXXXXX ) && \
trap 'rm -f "$TF"' EXIT HUP INT QUIT TERM && \
sed '/firmware_revision/ s/test/production/' myfile.py >"$TF" && \
mv -f "$TF" myfile.py

関連情報