用 sed 命令替换长字符串:参数列表太长错误

Lor*_*o B 9 bash sed shell-script

我正在尝试执行此命令

sed -i -e "s/BASE_64/$BASE_64/" FILE_NAME
Run Code Online (Sandbox Code Playgroud)

其中$BASE_64是文件内容的 base 64 表示。

sed 由于字符串太长,给我一个错误。

参数列表太长

怎样才能避免这个错误?

Sté*_*las 8

您总是可以这样做(因为您已经在使用 GNU sed( -i)):

sed -i -f - FILE_NAME << EOF
s/BASE_64/$BASE_64/g
EOF
Run Code Online (Sandbox Code Playgroud)

-f -告诉sed从标准输入读取 sed 脚本。

如果您想对多个文件重用相同的脚本,在 Linux(仅适用于 Linux)上,使用类似 的外壳zshksh并且bash版本高达 5.0,它在此处使用临时文件(而不是像dashor yash(或bash5.1+)这样的管道来实现文档)相对较小的 heredocs 并且仍然使用 GNU sed,您可以这样做:

find . -name '*.conf' -exec sed -i -f /dev/stdin {} + << EOF
s/BASE_64/$BASE_64/g
EOF
Run Code Online (Sandbox Code Playgroud)

在 Linux(仅限 Linux 和 Cygwin)上,/dev/stdin并不意味着stdin以同样的方式-。相反,它是在 stdin 上打开的文件的符号链接,因此每次sed打开它时,它都会从头开始重新打开文件。上面的命令可以在其他系统(具有/dev/stdin)或使用管道实现 here-documents 的 shell 上正常工作,但前提是只有很少的conf文件sed只被调用一次。第二次调用时,在非 Linux/Cygwin 系统上,如 with -f -/dev/stdin将显示为空,因为它已被第一次调用读取。

busybox sed-i以与 GNU 相同的方式支持sed,但不支持-f -. 所以-f /dev/stdin无论如何你都想在那里使用。使用 FreeBSD sed,使用:

sed -i '' -f /dev/stdin FILE_NAME << EOF
s/BASE_64/$BASE_64/g
EOF
Run Code Online (Sandbox Code Playgroud)


cas*_*cas 7

首先,将 base64 编码的数据保存在一个名为的文件中,例如base64.txt.

例如:

base64 < originalfile > base64.txt
Run Code Online (Sandbox Code Playgroud)

然后:

printf '%s\n' '/BASE64/r base64.txt' 1 '/BASE64/d' w | ed FILENAME
Run Code Online (Sandbox Code Playgroud)

这用于ed搜索FILENAME包含 string 的行,在该行之后BASE64插入内容base64.txt,返回到第一行,然后再次搜索包含 string 的行BASE64并将其删除。中的w命令ed保存修改后的文件。