Bash Grep-获取每次出现的行中的字符位置

Bash Grep-获取每次出现的行中的字符位置,bash,grep,cygwin,gnu,Bash,Grep,Cygwin,Gnu,根据手册,选项-b可以给出给定事件的字节偏移量,但它似乎从解析内容的开头开始 我需要检索grep返回的每个匹配内容的位置。我用了这句话,但很难看: grep '<REGEXP>' | while read -r line ; do echo $line | grep -bo '<REGEXP>' ; done grep''|在读取-r行时;做回显$line | grep-bo';完成 如何以更优雅的方式完成它,并更有效地使用GNUutils 例如: $ echo "a

根据手册,选项-b可以给出给定事件的字节偏移量,但它似乎从解析内容的开头开始

我需要检索grep返回的每个匹配内容的位置。我用了这句话,但很难看:

grep '<REGEXP>' | while read -r line ; do echo $line | grep -bo '<REGEXP>' ; done
grep''|在读取-r行时;做回显$line | grep-bo';完成
如何以更优雅的方式完成它,并更有效地使用GNUutils

例如:

$ echo "abcdefg abcdefg" > test.txt
$ grep 'efg' | while read -r line ; do echo $line | grep -bo 'efg' ; done < test.txt
4:efg
12:efg
$echo“abcdefg abcdefg”>test.txt
$grep'efg'|而read-r行;do echo$line | grep-bo'efg';完成

(实际上,此命令行不输出行号,但添加行号并不困难。)

Perl不是GNU util,但可以很好地解决您的问题:

perl -nle 'print "$.:$-[0]" while /efg/g'
在任何UNIX设备上的任何shell中使用任何awk(GNU或其他方式):

$ awk -v re='efg' -v OFS=':' '{
    end = 0
    while( match(substr($0,end+1),re) ) {
        print NR, end+=RSTART, substr($0,end,RLENGTH)
        end+=RLENGTH-1
    }
}' test.txt
1:5:efg
1:13:efg
awk中的所有字符串、字段、数组索引都从1开始,而不是从零开始,因此输出看起来与您的不一样,因为要awk,您的输入字符串是:

123456789012345
abcdefg abcdefg
而不是:

012345678901234
abcdefg abcdefg
如果您喜欢0索引字符串,可以将上面的代码更改为
end+=RSTART-1
end+=RLENGTH

已更新(单引号不嵌套)。请显示不起作用的输入。