使用通用 shell 解释器将包含带有 \n 的大文本的变量写入文件。你怎么做呢?

使用通用 shell 解释器将包含带有 \n 的大文本的变量写入文件。你怎么做呢?

环境:linux shell 或更好,busybox 中的 ash shell(示例系统:Openwrt)。

给定一个字符串变量大的文本"${a}"以这种方式构建:

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

考虑到尝试使用此变量作为通用命令的参数会产生错误,例如:

echo "${a}" #fails
awk -v VAR_A="${a}" '<program>' #fails

(失败的原因是:http://www.in-ulm.de/~mascheck/various/argmax/

如何将这样的变量写入文本文件,可能只使用简单的命令而不是 sed/awk/perl/其他强大的解释器。

理想情况下,文本文件应如下所示:

word 1
word 2
word 3
...

而不是像:

word 1\nword 2\nword 3\n...

更新1:有人问“为什么不能更改生成变量的脚本$a?”。因为我不能,因为,比如说,缺乏授权(“该脚本直到今天都有效,因此您可以只修复打印部分”)。所以$a它的格式已经给定了,我只能找到一种方法将其打印到文件中。

更新2:使用建议的“此处文档”解决了大部分问题,但我仍然将内容打印在一行中。也许是我的配置?

答案1

你可以做一个这里的文档并使用cat

$ cat <<EOT >output
$a
EOT
$ wc -l output
40000

我不知道你的 Busybox 到底有多强大ash(它是可配置的),但是它应该可以在任何地方工作,即使根本没有内置程序。它将变量值扩展为一个准文件,然后将其赋予cat,而不是将值本身放入命令行中。


由于您似乎想要"\n"删除字符串中的文字,因此您还可以在参数替换期间使用字符串替换。这是在 Busybox 之外配置的ash,在这种情况下,您必须转到sed.如果您确实有此(非 POSIX)扩展,您可以使用${var//\\\n/$NEWLINE}

$ busybox ash
$ foo="x\ny\nz"
$ echo "$foo"
x\ny\nz
$ NEWLINE="
"
$ echo "${foo//\\\n/$NEWLINE}"
x
y
z

这是相同的语法作为巴什; ${var/pattern/replacement}pattern如果以 开头,则全局位置在哪里/。看起来你ash已经配置了很多,所以这可能根本不存在。在这种情况下,您可能必须使用sed,尽管我认为明智地使用IFSandread会让您解决这个问题并重建正确的字符串。

答案2

busybox seq -s'
word ' 4000 | 
sed '/000/w /dev/fd/2' |  
wc -l

输出

word 1000
word 2000
word 3000
word 4000
4000

您应该能够使用busybox的内置函数seq并指定word为分隔符。然后,如果您愿意,您可以>redirect将其保存到文件中。在上面的示例中,我将其拆分为sed几个部分,以便您无需查看 4000 行即可了解输出 - 但它们都已打印。如果你busybox不支持这个,升级

所以基本上你需要做的$a就是:

busybox seq -s'
word ' $MAX_INCREMENT >$TO_FILE

相关内容