这会返回行号,但它们位于字符串中:
grep -n -F -w $word $file | cut -d : -f 1
答案1
我会用awk
这个,而不是grep
and cut
。要将行号放入数组中,请使用流程替代以及 bash 内置功能( in bashmapfile
的同义词是,但您可以通过运行在 bash 中获得比bash 更好、更详细的帮助)。例如:mapfile
readarray
help mapfile
help readarray
mapfile -t array < <(awk -v w="$word" '$0 ~ w {print NR}' "$file")
或者,使用固定字符串匹配而不是正则表达式匹配:
mapfile -t array < <(awk -v w="$word" 'index($0,w) {print NR}' "$file")
这两者都通过 awk 的选项将 shell 变量传递$word
给 awk 变量,因此无论它包含什么字符串都是安全的。比在双引号 awk 脚本中使用 $word 安全得多。w
-v
值得注意的是:如果有多个输入文件,您可能希望打印FNR
而不是NR
。NR 是迄今为止读取的所有行的累计总数。FNR 是行号当前文件仅有的。 (当我说“行”时,我真正的意思是“记录”,因为 awk 能够处理的不仅仅是带有换行符分隔记录的纯文本文件)
答案2
要将bash
行的内容读入数组,您可以使用readarray -t
(又名mapfile
,尽管这是一个用词不当,因为没有映射并且没有文件这里会导致与zsh/mapfile
模块zsh
及其$mapfile
特殊关联数组(真正映射文件)的混淆:
readarray -t array < <(
grep -nFwe "$word" -- "$file" | cut -d : -f 1
)
(顺便说一句,您忘记了扩展周围的--
和/或-e
和引号)。
或者,您可以使用 split+glob 运算符,并且由于它都是数字,因此您可以跳过禁用 glob:
IFS=$'\n'
array=( $(grep -nFwe "$word" -- "$file" | cut -d : -f 1) )
这样做的好处是可以保留管道的退出状态。
在 zsh 中,您可以使用f
参数扩展标志来分割在线f
eed,而无需修改$IFS
.
array=( ${(f)"$(grep -nFwe "$word" -- "$file" | cut -d : -f 1)" } )
不过,默认值$IFS
也可以在这里使用(并且没有什么理由$IFS
在 zsh 中进行修改):
array=( $(grep -nFwe "$word" -- "$file" | cut -d : -f 1) )