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

kol*_*nel 3 arrays bash text-parsing

我有一个名为failedfiles.txt以下内容的文件:

failed1
failed2
failed3
Run Code Online (Sandbox Code Playgroud)

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

temp_list=$(grep "[a-z]" failedfiles.txt)
Run Code Online (Sandbox Code Playgroud)

但是,这个问题是我打字的时候

echo ${temp_list[0]}
Run Code Online (Sandbox Code Playgroud)

我得到以下输出:

failed1 failed2 failed3
Run Code Online (Sandbox Code Playgroud)

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

echo ${temp_list[0]}
Run Code Online (Sandbox Code Playgroud)

打印

failed1
Run Code Online (Sandbox Code Playgroud)

当我这样做时:

echo ${temp_list[1]}
Run Code Online (Sandbox Code Playgroud)

打印

failed2
Run Code Online (Sandbox Code Playgroud)

谢谢.

mkl*_*nt0 11

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

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


阵列中一次捕获命令输出行:

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

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

注意:

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

循环命令输出行:

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

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