Replace a long string with the sed command: Argument list too long error
You could always do (since you're using GNU sed
already (-i
)):
sed -i -f - FILE_NAME << EOF
s/BASE_64/$BASE_64/g
EOF
-f -
tells sed
to read the sed script from stdin.
If you want to reuse the same script for several files, on Linux (and Linux only), with a shell like zsh
, ksh
and bash
version up to 5.0 that implements here documents with temporary files (as opposed to pipes like dash
or yash
(or bash
5.1+) for relatively small heredocs and still with GNU sed
, you could do:
find . -name '*.conf' -exec sed -i -f /dev/stdin {} + << EOF
s/BASE_64/$BASE_64/g
EOF
On Linux (and Linux and Cygwin only), /dev/stdin
does not mean stdin in the same way -
does. Instead, it's a symlink to the file open on stdin, so each time sed
opens it, it opens the file anew from the start. The above command would work OK on other systems (that have /dev/stdin
) or with shells that implement here-documents with pipes but only if there are few enough conf
files that sed
is called only once. When called the second time, on non-Linux/Cygwin systems, like with -f -
, /dev/stdin
would appear empty because it has already been read by the first invocation.
busybox
sed
also supports -i
in the same way as GNU sed
does, but does not support -f -
. So you'd want to use -f /dev/stdin
there in any case. With FreeBSD sed
, use:
sed -i '' -f /dev/stdin FILE_NAME << EOF
s/BASE_64/$BASE_64/g
EOF
First, save the base64-encoded data in a file called, e.g., base64.txt
.
For example:
base64 < originalfile > base64.txt
Then:
printf '%s\n' '/BASE64/r base64.txt' 1 '/BASE64/d' w | ed FILENAME
This uses ed
to search in FILENAME
for a line containing the string BASE64
, insert the contents of base64.txt
after that line, go back to the first line, then search for the line with string BASE64
again and delete it. The w
command in ed
saves the modified file.
Another option would be to replace sed
with ed
and store your commands in a file. For example, if you create ed_cmds
with the following contents:
%s/BASE_64/<expanded variable>/g
w
q
you could then run
< ed_cmds ed FILE_NAME
and it would make the changes you wanted, so instead of setting $BASE_64
you'd create the ed command file.
Ed Explanation
%
means to apply the command to each line of the files/pat1/pat2/g
substitutes occurrences ofpat1
withpat2
andg
at the end makes it do it for every match on the line, not just the firstw
write the changes to diskq
quit (which would happen when it got EOF anyway)
Of course, you could put your sed
commands in a file and use -f
as well, but if you're doing that and you want to modify the file in place you might as well use ed
instead of creating a temporary file and moving it as sed -i
does.