如何将命令的输出分配到数组中?

cei*_*cat 63 arrays bash command-substitution

我需要将结果从a分配grep给一个数组......例如

grep -n "search term" file.txt | sed 's/:.*//'
Run Code Online (Sandbox Code Playgroud)

这导致了一系列行号,其中找到了搜索词.

1
3
12
19
Run Code Online (Sandbox Code Playgroud)

将它们分配给bash数组的最简单方法是什么?如果我只是将它们分配给变量,它们就会变成一个以空格分隔的字符串.

jor*_*anm 117

要将输出分配给数组,需要在数组赋值内使用命令替换.

arr=( $(command) )
Run Code Online (Sandbox Code Playgroud)

内部$()运行命令,而outer()使输出成为数组.这样做的问题是它不适用于包含空格的文件.要处理此问题,您可以将IFS设置为\n.

arr=($(grep -n "search term" file.txt | sed 's/:.*//'))
Run Code Online (Sandbox Code Playgroud)

您还可以通过对阵列的每个元素执行扩展来减少对sed的需求:

IFS=$'\n'
arr=($(grep -n "search term" file.txt | sed 's/:.*//'))
unset IFS
Run Code Online (Sandbox Code Playgroud)

  • 请注意, `array=( $(command) )` 被视为反模式,并且是 [BashPitfalls #50](http://mywiki.wooledge.org/BashPitfalls#hosts.3D.28_.24.28aws_.. ..29_.29)。 (5认同)
  • 加上一个用于处理元素中具有空格的案例.正是我在寻找什么. (3认同)
  • IFS的东西很棒!找了几个小时! (2认同)
  • 作为一种更好的实践方法,仍然与 bash 3.x 兼容,请考虑 `read -r -d '' -a arr < <(grep ... | sed ... && printf '\0')`,这可以避免对 `command` 的输出进行通配和字符串分割,并且 _also_ 从管道中传递非零退出状态(将它们全部合并为 1,因为缺少尾随分隔符会使 `read` 失败) (2认同)

Shi*_*dim 8

空格分隔的字符串很容易在bash中遍历.

# save the ouput
output=$(grep -n "search term" file.txt | sed 's/:.*//')

# iterating by for.
for x in $output; do echo $x; done;

# awk
echo $output | awk '{for(i=1;i<=NF;i++) print $i;}'

# convert to an array
ar=($output)
echo ${ar[3]} # echos 4th element
Run Code Online (Sandbox Code Playgroud)

如果您正在考虑使用文件名中的空格 find . -printf "\"%p\"\n"

  • 但是对于带有空格 (3认同)

Asf*_*azi 7

@Charles Duffy 在评论中链接了 Bash 反模式文档,这些文档给出了最正确的答案:

\n
readarray -t arr < <(grep -n "search term" file.txt | sed \'s/:.*//\')\n
Run Code Online (Sandbox Code Playgroud)\n

他的评论:

\n
\n

请注意, array=( $(command) ) 被视为反模式,并且是BashPitfalls #50的主题。\xe2\x80\x93 查尔斯·达菲 2020 年 11 月 16 日 14:07

\n
\n