如何从命令输出的行创建数组

时间:2014-04-01 03:22:55

标签: arrays bash text-parsing

我有一个名为failedfiles.txt的文件,其中包含以下内容:

failed1
failed2
failed3

我需要使用grep返回该文件中每行的内容,并将输出保存在要访问的列表中。所以我想要这样的东西:

temp_list=$(grep "[a-z]" failedfiles.txt)

然而,问题是当我输入

echo ${temp_list[0]}

我得到以下输出:

failed1 failed2 failed3

但我想要的是当我这样做时:

echo ${temp_list[0]}

打印

failed1

当我这样做时:

echo ${temp_list[1]}

打印

failed2

感谢。

3 个答案:

答案 0 :(得分:9)

@ devnull的有用答案解释了为什么你的代码没有按预期工作:命令替换总是返回单个字符串(可能由多行组成)。

但是,如果命令输出的行没有嵌入空格,简单地将(...)放在命令替换周围以创建数组只会按预期工作。 - 否则,每个单独的(以空格分隔的)单词将成为自己的数组元素。


数组

中一次捕获命令输出行

要捕获数组中任意命令输出的行,请使用以下命令:

  • bash< 4 (例如,从OS X 10.9.2开始的OSX上):使用read -a
IFS=$'\n' read -rd '' -a linesArray <<<"$(grep "[a-z]" failedfiles.txt)"
  • bash&gt; = 4 :使用readarray
readarray -t linesArray <<<"$(grep "[a-z]" failedfiles.txt)"

注意:

  • <<<启动一个所谓的here-string,它通过{{1}将字符串右侧(这恰好是此处命令替换的结果)传递到左侧的命令中}。
    • 虽然原则上stdin在功能上等同于command <<< string,但关键的区别在于后者会创建子shell ,这会使echo string | command中的变量赋值毫无意义 - 它们被本地化到每个子shell。
  • 将here-strings与命令替换结合起来的替代方法是[input] process substitution - command - 简单地说,它允许使用命令的输出,就好像它是输入文件一样;等同于<(...)的是<<<"$(command)"
  • < <(command)read读入一个数组,-a确保每一行都被视为一个单独的字段,从而读入自己的数组元素; IFS=$'\n'确保一次读取所有行(在将它们分成字段之前); -d ''将输入中的转义序列解释为关闭。
  • -r(也可以调用readarray)直接将输入行分成一行数组; mapfile确保终止-t不包含在数组元素中。

循环 over命令输出行:

如果不需要一次性捕获阵列中的所有行并且循环,则逐行输出命令的输出就足够了,请使用以下命令:

\n
  • while IFS= read -r line; do # ... done < <(grep "[a-z]" failedfiles.txt) 确保每行都以空白方式不加修改地读取;删除它以修剪前导和尾随空格。
  • IFS=确保线条被读取&#39; raw&#39;在输入中看起来像转义序列的子串 - 例如,-r - 不会被解释为这样。
  • 注意使用[input]进程替换(如上所述)提供命令输出作为\t循环的输入。

答案 1 :(得分:3)

你做了创建一个数组。你所做的是Command Substitution,它只是将命令的输出放入变量

为了创建一个数组,请说:

temp_list=( $(grep "[a-z]" failedfiles.txt) )

您可能还想引用Guide on Arrays

答案 2 :(得分:2)

循环文件中的行的正确且可移植的方法就是

while read -r line; do
    ... something with "$line"
done <failedfiles.txt