问题描述
我想打印一个数组,其中每个元素都在一行上,以便我可以将其通过管道传输到其他工具。
示例:
> set foo "A 1" "B 3" "C 9"
> echo $foo
A 1 B 3 C 9 <-- Not clear what the elements are!
> for i in $foo; echo $i; end; <-- Too verbose for working
注意:使用 tr/sed/string join
不是我正在寻找的解决方案,不能保证任何元素都不会包含 ~~换行符~~或空格/制表符。
解决方法
检查变量 set -S foo
或 set --show foo
的内容很好。
set foo "A 1" "B 3" "C 9" "element
with
newlines"
set -S foo
节目
$foo: set in global scope,unexported,with 3 elements
$foo[1]: |A 1|
$foo[2]: |B 3|
$foo[3]: |C 9|
$foo[4]: |element\nwith\nnewlines|
这是fish v3.2.0——我记得,早期版本有更详细的细节。
或者,printf
带有一些开始/结束标记:
$ printf '>>%s<<\n' $foo
>>A 1<<
>>B 3<<
>>C 9<<
>>element
with
newlines<<
,
注意:使用 tr/sed/string join 不是我正在寻找的解决方案,不能保证任何元素都不会包含换行符或空格字符。
如果您的元素可以包含换行符,则在一行上打印每个元素已经被破坏了。
例如
set foo a\nb c
你可以用
打印这个printf %s\n $foo
但它会导致
a
b
c
所以无论你用管道输入什么命令,它都不知道“a\nb”是一个元素。
就像其他人所说的,要展示一个变量包含的内容,您可以使用 set --show foo
或类似的东西
printf '|%s|\n' $foo
但是将它传递给命令时这不起作用,因为它不知道您的格式是什么。
您需要重新考虑您的数据格式或将数据作为参数传递,而不是通过标准输入。您需要做什么完全取决于您正在调用哪个命令以及它应该做什么。
如果您的命令具有读取空分隔输入的开关,您可以使用 string join0
之类的
string join0 $foo | baz --read0
例如,如果 $foo 是一个文件列表,而您想对它们使用 du
string join0 $foo | du --files0-from=-
虽然在这种情况下你也可以像这样直接将它们作为参数传递
du $foo