【问题标题】:How do I assign the output of a command into an array?如何将命令的输出分配到数组中?
【发布时间】:2012-02-26 00:25:33
【问题描述】:

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

grep -n "search term" file.txt | sed 's/:.*//'

这导致了一堆带有行号的行,其中找到了搜索词。

1
3
12
19

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

【问题讨论】:

  • 空格分隔的字符串在 bash 中很容易遍历。
  • 哦...应该搜索得更彻底。谢谢。
  • 顺便说一句,一个常见的反模式使用grep 来获取某些东西的行号,并最终将它们传递给一个自己支持正则表达式的工具。然后它可以找到与找到的grep 相同的行,而无需绕道找出匹配的行号。

标签: arrays bash command-substitution


【解决方案1】:

要将命令的输出分配给数组,您需要在数组分配中使用命令替换。对于一般命令command,它看起来像:

arr=( $(command) )

在 OP 的示例中,这将显示为:

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

内部$() 运行命令,而外部() 导致输出为数组。这样做的问题是当命令的输出包含空格时它将不起作用。要处理这个问题,您可以将IFS 设置为\n

IFS=$'\n' arr=($(grep -n "search term" file.txt | sed 's/:.*//'))

您还可以通过对数组的每个元素执行扩展来消除对 sed 的需求:

arr=($(grep -n "search term" file.txt))
arr=("${arr[@]%%:*}")

【讨论】:

  • 对我来说它只工作没有外括号dvmList=`grep -RohP '(?<=oramds:).+\.dvm' myFolder`
  • @bastaPasta 这不是数组赋值。如果您没有使用支持数组的 shell,数组分配可能对您不起作用。
  • 你说得对,我使用的是 sh 而不是 bash,但它在 for 中循环运行良好
  • @bastaPasta 是的,只要您的“元素”不包含空格,它就会。还有其他方法可以通过set 和特殊数组$@ 来模拟没有数组的shell。
  • 请注意,array=( $(command) ) 被视为反模式,是BashPitfalls #50 的主题。
【解决方案2】:

空格分隔的字符串在 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

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

【讨论】:

  • 但是对于带有空格的文件会损坏。
  • @jordanm 使用 find . -printf "\"%p\"\n"
  • @ShipluMokaddim,这不起作用。 for x in $output 与这样的find 命令将导致名为two words 的文件被迭代为一个值"two 和另一个值words"
  • @ShipluMokaddim, ...如果您使用ar=( $output ) 并以这种方式分配output,情况也是如此,因为参数扩展和命令替换结果不会经过引号删除解析阶段。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-28
  • 2011-01-02
  • 2012-10-10
  • 2017-07-21
  • 1970-01-01
  • 2016-02-12
  • 1970-01-01
相关资源
最近更新 更多