![使用通用 shell 解释器将包含带有 \n 的大文本的变量写入文件。你怎么做呢?](https://linux22.com/image/41101/%E4%BD%BF%E7%94%A8%E9%80%9A%E7%94%A8%20shell%20%E8%A7%A3%E9%87%8A%E5%99%A8%E5%B0%86%E5%8C%85%E5%90%AB%E5%B8%A6%E6%9C%89%20%5Cn%20%E7%9A%84%E5%A4%A7%E6%96%87%E6%9C%AC%E7%9A%84%E5%8F%98%E9%87%8F%E5%86%99%E5%85%A5%E6%96%87%E4%BB%B6%E3%80%82%E4%BD%A0%E6%80%8E%E4%B9%88%E5%81%9A%E5%91%A2%EF%BC%9F.png)
环境: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
,尽管我认为明智地使用IFS
andread
会让您解决这个问题并重建正确的字符串。
答案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