web-dev-qa-db-ja.com

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

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

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

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

sedは、文字列が長すぎるためエラーになります。

引数リストが長すぎます

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

7
Lorenzo B

最初に、base64でエンコードされたデータをbase64.txtなどのファイルに保存します。

例えば:

base64 < originalfile > base64.txt

次に:

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

これはedを使用してFILENAMEで文字列BASE64を含む行を検索し、その行の後にbase64.txtの内容を挿入して、最初の行に戻ります。文字列BASE64の行をもう一度検索して削除します。 wedコマンドは、変更されたファイルを保存します。

5
cas

あなたはいつでもできます(GNU sedをすでに使用しているため(-i)):

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

-f -は、sedにstdinからsedスクリプトを読み取るように指示します。

Linux(およびLinuxのみ)で、bashzshkshのようなシェルを使用して複数のファイルに同じスクリプトを再利用する場合は、ここに一時的なドキュメントを実装しますファイル(dashyashのようなパイプとは対照的に)とGNU sedを使用して、次のことができます:

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

Linux(およびLinuxのみ)では、/dev/stdin-と同じようにstdinを意味しません。代わりに、stdinで開いているファイルへのシンボリックリンクであるため、sedがファイルを開くたびに、最初からファイルを開きます。上記のコマンドは、他のシステム(/dev/stdinがあるシステム)またはパイプを使用してヒアドキュメントを実装するシェルで正常に機能しますが、confファイルが十分に少なく、sedが1回だけ呼び出される場合に限ります。 -f -のようなLinux以外のシステムで2回目に呼び出された場合、/dev/stdinは最初の呼び出しですでに読み取られているため、空に表示されます。

busyboxsedもGNU sedと同じ方法で-iをサポートしていますが、-f -はサポートしていません。したがって、いずれの場合も-f /dev/stdinを使用してください。FreeBSDsedでは、次のように使用します。

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

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

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

その後、実行できます

< ed_cmds ed FILE_NAME

必要な変更が加えられるため、$BASE_64を設定する代わりに、edコマンドファイルを作成します。

編集内容

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

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

4
Eric Renouf

ファイル($ BASE_64)のBase64表現のサイズが長すぎ、最大引数サイズを超えています。実行すると、システムのこの制限を確認できるはずです

getconf ARG_MAX

ARG_MAX値のサイズを増やす必要があります。しかし、ファイルが大きすぎる場合は、この置換を行うために別のアプローチを使用する必要があると思います。 Pythonスクリプトがそれをやってくれるなら、私もそれを試してみます。

2
mazs

sed命令をファイルに入れてしまいました

SEDCOMMANDS=`tempfile`

そして呼ばれた

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

sed -iを使用しない場合に適しています。ファイルをその場で編集する場合は、 https://unix.stackexchange.com/a/284188/149867 に従い、同等のed指示をファイルに入れて、 wおよびq

2
cayhorstmann