如何从$ x行号开始在文件中查找字符串的下一个匹配项。

时间:2018-10-25 11:51:22

标签: bash

在下面的示例中,我将变量$ line设置为“ 14”,它与文件的第14行即“第四”相关。

我需要在BASH中找到一种方法,以从($ line)(14)中设置的行号开始,并找到同一文件中下一次出现的字符串(foo)的行号。在这种情况下,结果将是第16行。

one
foo
bar
foo
two
foo
three
foo
foo
bar
foo
foo
foo
four
bar
foo
bar
five
foo
six
foo
foo
bar
foo

$line = "14"
$search = "foo"

3 个答案:

答案 0 :(得分:2)

很多方法可以做到这一点。但是,如果您想单独使用bash进行操作(即不使用awk,perl等),则可以采用以下一种方法:

$ mapfile -t -O 1 a < ttt
$ for ((i=$line; i<=${#a[@]}; i++)); do [[ "${a[$i]}" = "$string" ]] && echo "$i" && break; done

mapfile命令将文件吸收到一个数组中(以比循环中的read更好的方式),而-O 1使它开始从1开始对数组索引编号而不是0。for循环从$line开始,以[[遍历数组,该数组将当前数组值与$string进行比较。

我仍然很想知道您提出了什么解决方案,并帮助您了解为什么它行不通。

答案 1 :(得分:1)

尝试awk:

line=14
search=foo
awk '(NR > n && $0 == s){ print NR; exit }' n=$line s="$search" file

输出:

16

您可以通过以下方式将结果分配给变量:

declare -i var=$(awk '(NR > n && $0 == s){ print NR; exit }' n=$line s="$search" file)

答案 2 :(得分:1)

sed单线-

使用您的数据,将其命名为“ infile”,我得到

$: line=14 search=foo sed -n $line,\${/$search/\{=\;q}} infile
16

这将在执行sed之前为env设置变量,并告诉它不要输出-n尚未提出的任何内容。

命令$line,\${/$search/\{=\;q}}的计算结果为14,${/foo/{=;q}}

这意味着“从第14行到末尾,找到其中包含“ foo”的下一行,然后

  

打印行号(=)并

     

退出(q),而不处理文件的其余部分。