我有一个名为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
感谢。
答案 0 :(得分:9)
但是,如果命令输出的行没有嵌入空格,简单地将(...)
放在命令替换周围以创建行数组只会按预期工作。 - 否则,每个单独的(以空格分隔的)单词将成为自己的数组元素。
要捕获数组中任意命令输出的行,请使用以下命令:
read -a
IFS=$'\n' read -rd '' -a linesArray <<<"$(grep "[a-z]" failedfiles.txt)"
readarray
:readarray -t linesArray <<<"$(grep "[a-z]" failedfiles.txt)"
注意:
<<<
启动一个所谓的here-string,它通过{{1}将字符串右侧(这恰好是此处命令替换的结果)传递到左侧的命令中}。
stdin
在功能上等同于command <<< string
,但关键的区别在于后者会创建子shell ,这会使echo string | command
中的变量赋值毫无意义 - 它们被本地化到每个子shell。command
- 简单地说,它允许使用命令的输出,就好像它是输入文件一样;等同于<(...)
的是<<<"$(command)"
。< <(command)
:read
读入一个数组,-a
确保每一行都被视为一个单独的字段,从而读入自己的数组元素; IFS=$'\n'
确保一次读取所有行(在将它们分成字段之前); -d ''
将输入中的转义序列解释为关闭。-r
(也可以调用readarray
)直接将输入行分成一行数组; mapfile
确保终止-t
不包含在数组元素中。如果不需要一次性捕获阵列中的所有行并且循环,则逐行输出命令的输出就足够了,请使用以下命令:
\n
while IFS= read -r line; do
# ...
done < <(grep "[a-z]" failedfiles.txt)
确保每行都以空白方式不加修改地读取;删除它以修剪前导和尾随空格。IFS=
确保线条被读取&#39; raw&#39;在输入中看起来像转义序列的子串 - 例如,-r
- 不会被解释为这样。\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