我需要将grep
命令的结果赋值给一个数组...例如:
grep -n "search term" file.txt | sed 's/:.*//'
这导致出现了许多带有行号的行,其中包含搜索项。
1
3
12
19
最简单的方法是将它们分配给一个Bash数组。如果只是分配给一个变量,它们会变成以空格分隔的字符串。
我需要将grep
命令的结果赋值给一个数组...例如:
grep -n "search term" file.txt | sed 's/:.*//'
这导致出现了许多带有行号的行,其中包含搜索项。
1
3
12
19
最简单的方法是将它们分配给一个Bash数组。如果只是分配给一个变量,它们会变成以空格分隔的字符串。
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[@]%%:*}")
set
和特殊数组$@
实现。 - jordanmread -r -d''-a arr < <(grep ... | sed ... && printf'\0')
,它避免了对command
输出进行全局匹配和字符串分割,并且还通过管道传递非零退出状态(将它们合并为1,因为缺少尾部定界符会使read
失败)。 - Charles Duffyagvtool
在每行输出末尾留下尾随空格) - levigroker用空格分隔的字符串在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"
find . -printf "\"%p\"\n"
- Shiplu Mokaddimfor x in $output
将导致一个名为“two words”的文件被迭代为一个值“two”和另一个值“words”。 - Charles Duffyar =($output)
并以这种方式分配output
,则同样的情况也是正确的,因为参数扩展和命令替换结果不会通过引号删除解析阶段。 - Charles Duffy@Charles Duffy在评论中提供了Bash反模式文档,这些文档给出了最正确的答案:
readarray -t arr < <(grep -n "search term" file.txt | sed 's/:.*//')
他的评论:
注意,array=( $(command) ) 被认为是反模式,并且是 BashPitfalls #50 的主题。- Charles Duffy 于2020年11月16日14:07
grep
获取某些内容的行号并最终将它们传递给具有自己的正则表达式支持的工具是一种常见的反模式。然后它可以找到与grep
找到的相同行,而不必绕过匹配行号的步骤。 - tripleee