我将数据附加到文件中,然后使用
echo "$(tail -n10 newdata.txt)" > newdata.txt;
文件中仅保留 10 行newdata.txt
。
我想读取这个文件并将其所有内容存储在一个变量中,以便当我执行
{"Value":" "} | jq .
创建一个 JSON 文件。我将能够仅将所有 10 个值写入一个关键字value
。
我试过
value=cat newdata.txt
但这给了我解析错误:
Invalid string: control characters from U+0000 through U+001F must be escaped.
答案1
这是一XY问题。要将文件的内容分配newdata.txt
给变量lines
,请使用:
lines="$(cat newdata.txt)"
但是为什么要将 的内容分配newdata.txt
给变量呢?
您期望的结果是一个 JSON 对象,其字段value
的内容newdata.txt
为 的值。的内容newdata.txt
是纯文本,而不是 JSON,因此回显{"value", $(cat newdata.txt)}
或等效{"value", $lines}
的内容jq .
将不起作用,因为jq
需要读取有效的 JSON。
那么实际的问题是:如何将纯文本行转换为 JSON?
jq
可以使用选项,将任意输入行解析为 JSON 字符串流-R
。--raw-input
要一次解析所有输入行,请使用选项-s
, --slurp
。然后输入可用于常规jq
流处理,因此:
jq -sR '{"value", .}' newdata.txt
将给出所需的 JSON 对象。
另一方面,echo "$(tail -n10 newdata.txt)" > newdata.txt
必然会间歇性地失败。在有机会读取最后 10 行之前>newdata.txt
,很有可能截断newdata.txt
为 0 字节。tail
您可以使用它sponge
来解决此问题,但请参阅下文。
另外,为什么echo
? tail -n 10
已经回显到标准输出,因此无需将其输出捕获到字符串中,只需echo
再次将其回显到标准输出即可。
结合所有这些,单行解决方案将是:
tail -n 10 olddata.txt | tee newdata.txt | jq -sR '{"value", .}' &&
mv newdata.txt olddata.txt
bash
具有其他编程语言的所有功能,例如变量和字符串,但将其视为从 stdin 读取并写入 stdout 的流处理器会更有效率。
答案2
尝试:
value=$(perl -e 'print qx/cat newdata.txt/;')
这使用“-e”让您定义要由编译器执行的 Perl 代码。
$() 使您可以捕获命令的输出并将其分配给 shell 变量。
答案3
我想到了。我正在为需要的人发布答案。我将数据附加到名为 newdata.txt 的文件中,如下所示:echo "$(tail -n10 newdata.txt)" > newdata.txt;
然后我只是将文件复制到一个名为 value 的变量: value="$(cat newdata.txt)"
完成后echo "{\"Values\":[$value]}" | jq .
我得到了 JSON 对象。
唯一有效的方法是除了最后一行之外,每行末尾都有一个逗号。
我不确定这是否是万无一失且正确的方法。但这对我的问题有用。