Environment: linux shell or better, ash shell in busybox (example system: Openwrt).
Given a string variable with large text "${a}"
constructed in this way:
for index in $(seq 1 40000); do #it is 40000 for a reason, it helps if you want to reproduce the error on your system.
a="${a}""\n""word ${index}"
done
and given the fact that trying to use this variable as argument for common command produce an error, for example:
echo "${a}" #fails
awk -v VAR_A="${a}" '<program>' #fails
(the failures are due: http://www.in-ulm.de/~mascheck/various/argmax/ )
How do you write such a variable to a text file, possibly using only simple commands and not sed/awk/perl/other powerful interpreter.
Ideally the text file should look like:
word 1
word 2
word 3
...
and not like:
word 1\nword 2\nword 3\n...
Update1: Someone asks "Why you cannot change the script that produce the variable $a
?". Because i cannot due to, let's say, lack of authorization ("the script was working until today, so you can fix only the printing part"). So $a
and its format is given, i can only find a way to print it to a file.
Update2: Using the suggested "here docs" solve most of the problems but still i have the content printed in one line. Maybe is my config?
Best Answer
You can make a here document and use
cat
:I don't know exactly how powerful your Busybox's
ash
is (it's configurable), but that should work anywhere, even with no builtins at all. It expands the variable value into a quasi-file, which is then given tocat
, rather than putting the value itself into the command line.Since you seem to have literal
"\n"
in your string that you want to get rid of, you can also use string replacement during parameter subsitution. This can be configured out of Busybox'sash
, in which case you'll have to go tosed
. If you do have this (non-POSIX) extension, you can use${var//\\\n/$NEWLINE}
:This is the same syntax as Bash;
${var/pattern/replacement}
, wherepattern
is global if it starts with/
. It seems yourash
has a lot configured out of it, so this might not be there at all. In that case you're probably going to have to go withsed
, although I guess judicious use ofIFS
andread
would let you work around that and reconstruct a correct string.