sed コマンドで長い文字列を置換する: 引数リストが長すぎるというエラー

sed コマンドで長い文字列を置換する: 引数リストが長すぎるというエラー

このコマンドを実行しようとしています

sed -i -e "s/BASE_64/$BASE_64/" FILE_NAME

ここで、は$BASE_64ファイル コンテンツの Base 64 表現です。

sed文字列が長すぎるためエラーが発生します。

引数リストが長すぎます

このエラーを回避するにはどうすればよいでしょうか?

答え1

常に次の操作を実行できます (sedすでに GNU ( -i) を使用している場合):

sed -i -f - FILE_NAME << EOF
s/BASE_64/$BASE_64/g
EOF

-f -sedstdin から sed スクリプトを読み込むように指示します。

Linux (Linux のみ) 上で、 のようなシェルと、一時zshファイルを使用してヒアドキュメントを実装するバージョン 5.0 まで (比較的小さなヒアドキュメントの場合はや(または5.1+)のようなパイプではなく)、GNU を使用し、複数のファイルに同じスクリプトを再利用したい場合は、次のようにします。kshbashdashyashbashsed

find . -name '*.conf' -exec sed -i -f /dev/stdin {} + << EOF
s/BASE_64/$BASE_64/g
EOF

Linux(LinuxとCygwinのみ)では/dev/stdin標準入力と同じように-機能します。代わりに、これは標準入力で開いているファイルへのシンボリックリンクなので、 がsedファイルを開くたびに、ファイルが最初から新しく開かれます。上記のコマンドは、他のシステム ( がある) や、パイプでヒアドキュメントを実装するシェルでも問題なく機能しますが、ファイルが1 回だけ呼び出される/dev/stdin場合に限られます。 の場合と同様に、Linux/Cygwin 以外のシステムで 2 回目に呼び出されると、最初の呼び出しで既に読み込まれているため、空として表示されます。confsed-f -/dev/stdin

busybox sed-iGNU と同じようにサポートしsedていますが、 はサポートしていません。したがって、いずれにしても-f -を使用する必要があります。FreeBSD では、次のように使用します。-f /dev/stdinsed

sed -i '' -f /dev/stdin FILE_NAME << EOF
s/BASE_64/$BASE_64/g
EOF

答え2

まず、base64 でエンコードされたデータを、たとえば というファイルに保存しますbase64.txt

例えば:

base64 < originalfile > base64.txt

それから:

printf '%s\n' '/BASE64/r base64.txt' 1 '/BASE64/d' w | ed FILENAME

これは、 を使用してで文字列 を含む行をed検索し、その行の後に の内容を挿入し、最初の行に戻って、文字列 を含む行を再度検索して削除します。のコマンドは、変更されたファイルを保存します。FILENAMEBASE64base64.txtBASE64wed

答え3

sedもう 1 つのオプションは、コマンドを に置き換えてファイルに保存することですed。たとえば、ed_cmds次の内容で作成したとします。

%s/BASE_64/<expanded variable>/g
w
q

その後、実行することができます

< ed_cmds ed FILE_NAME

必要な変更が行われるので、設定する代わりに$BASE_64ed コマンド ファイルを作成します。

エドの説明

  • %ファイルの各行にコマンドを適用することを意味します
  • s/pat1/pat2/gpat1の出現箇所を最後に置換するpat2と、g最初の一致だけでなく、行内のすべての一致に対して実行されます。
  • w変更内容をディスクに書き込む
  • q終了する(いずれにせよ EOF を取得したときに発生します)

もちろん、sedコマンドをファイルに入れて を使用すること-fもできますが、その場合、ファイルをその場で変更したいときは、edのように一時ファイルを作成して移動する代わりにを使用する方がよいでしょうsed -i

答え4

sed私は指示をファイルにまとめました

SEDCOMMANDS=`tempfile`

そして呼ばれる

sed -f "$SEDCOMMANDS" -- "$FILE_NAME"

を使わない場合はこれで問題ありませんsed -i。ファイルをその場で編集したい場合は、https://unix.stackexchange.com/a/284188/149867同等のed命令をファイルに入れて、その後にwと を続けますq

関連情報