我正在尝试执行这个命令
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 -
告诉sed
从 stdin 读取 sed 脚本。
如果您想在 Linux(且仅限 Linux)上对多个文件重用相同的脚本,请使用类似于 的 shell zsh
,版本高达 5.0 ksh
,bash
它使用临时文件实现此处文档(而不是像dash
or yash
(或bash
5.1+)这样的管道相对较小的heredocs并且仍然使用GNU sed
,你可以这样做:
find . -name '*.conf' -exec sed -i -f /dev/stdin {} + << EOF
s/BASE_64/$BASE_64/g
EOF
在 Linux 上(仅限 Linux 和 Cygwin),/dev/stdin
并不意味着标准输入以同样的方式-
。相反,它是指向在标准输入上打开的文件的符号链接,因此每次sed
打开它时,它都会从头开始重新打开该文件。上面的命令在其他系统(具有/dev/stdin
)或使用通过管道实现此处文档的 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
答案2
首先,将 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
再次搜索包含字符串的行并将其删除。该w
命令ed
保存修改后的文件。
答案3
另一种选择是将命令替换sed
为ed
并将命令存储在文件中。例如,如果您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
我最终将sed
说明放入文件中
SEDCOMMANDS=`tempfile`
并打电话给
sed -f "$SEDCOMMANDS" -- "$FILE_NAME"
如果你不使用的话也很好sed -i
。如果您想就地编辑文件,请按照https://unix.stackexchange.com/a/284188/149867并将等效ed
指令放入文件中,后跟w
和q
。