【问题标题】:How to create an array from the lines of a command's output如何从命令输出的行创建数组
【发布时间】:2014-05-11 15:43:53
【问题描述】:

我有一个名为 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

谢谢。

【问题讨论】:

  • 您能解释一下为什么您认为需要将行添加到数组中吗?您要解决的根本问题是什么?

标签: arrays bash text-parsing


【解决方案1】:

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

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


数组中一​​次捕获命令输出行:

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

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

注意:

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

循环命令输出行:

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

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

【讨论】:

    【解决方案2】:

    循环遍历文件中的行的适当且可移植的方法很简单

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

    【讨论】:

    • 谢谢先生的评论。
    【解决方案3】:

    您确实没有创建了一个数组。你所做的是Command Substitution,它将简单地将命令的输出放入一个变量

    为了创建一个数组,说:

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

    您可能还想参考Guide on Arrays

    【讨论】:

    • grep 不返回找到匹配模式的行的列表吗?
    • 所以我的论点(其实我只是想理解大师)我没有将返回类型分配给 temp_list 吗?
    • 是的,确实如此。您能否详细说明您要澄清的内容?
    • @kolonel 我不确定您所说的返回类型是什么意思。但是,您所做的只是将程序的输出分配给名为temp_list 的变量。它没有创建数组。如果您在打印时引用变量,您可能会想到:echo "$temp_list"
    • @kolonel 添加了一些可能有帮助的链接。
    猜你喜欢
    • 2018-01-01
    • 2020-09-08
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 2011-05-10
    • 2022-01-02
    • 1970-01-01
    相关资源
    最近更新 更多