Bash-匹配正则表达式的多行数字(可能是单行吗?)

时间:2018-07-04 18:10:19

标签: regex bash

我对bash不太熟练,但积极尝试改进,因此我想请一些专家提出一些建议:)

假设我有以下文本文件:

Some
spam
about which I don't care.
I want following letters:
X1
X2
X3
I do not want these:
X4
X5
Nor this:
X6
But I'd like these, too:
I want following letters:
X7
And so on...

我想获取带有这些字母的行数,因此所需的输出应如下所示:
5 6 7 15

为了阐明这一点:我希望所有与某个正则表达式/\s*X./匹配的行都在与另一个正则表达式/\sI want following letters:/匹配之后立即出现

现在我有一个可行的解决方案,我不太喜欢:

cat data.txt | grep -oPz "\sI want following letters:((\s*X.)*)" | grep -oPz "\s*X." > tmp.txt

for entry in $(cat tmp.txt); do
 grep -n $entry data.txt | cut -d ":" -f1
done

我的问题是:是否有任何聪明的方法,我不知道的任何工具都具有可以在一行中完成此功能的功能? (我特别不喜欢在这里使用临时文件和循环)

3 个答案:

答案 0 :(得分:3)

您可以使用awk

awk '/I want following/{p=1;next}!/^X/{p=0;next}p{print NR}' file

多行版本的说明:

#!/usr/bin/awk

/I want following/{
    # Just set a flag and move on with the next line
    p=1
    next
}

!/^X/ {
    # On all other lines that doesn't start with a X
    # reset the flag and continue to process the next line
    p=0
    next
}

p {
    # If the flag p is set it must be a line with X+number.
    # print the line number NR
    print NR
}

答案 1 :(得分:1)

以下内容可能会对您有所帮助。

awk '!/X[0-9]+/{flag=""} /I want following letters:/{flag=1} flag'  Input_file

如果您不想使用这些行,则上面还将打印包含I want following letters:的行,然后使用following。

awk '!/X[0-9]+/{flag=""} /I want following letters:/{flag=1;next} flag' Input_file

要在输出中添加行号,请使用以下

awk '!/X[0-9]+/{flag=""} /I want following letters:/{flag=1;next} flag{print FNR}' Input_file

答案 2 :(得分:0)

首先,让我们对当前脚本进行一些优化:

#!/bin/bash

FILE="data.txt"

while read -r entry; do
  [[ $entry ]] && grep -n $entry "$FILE" | cut -d ":" -f1
done < <(grep -oPz "\sI want following letters:((\s*X.)*)" "$FILE"| grep -oPz "\s*X.")

这里有一些评论:

  • 无需使用cat file|grep ... => grep ... file
  • 请勿使用语法for i in $(command),这通常是导致多个错误的原因,并且总是a smarter solution
  • 也无需使用tmp文件

然后,有很多更短的解决方案。这是使用awk的一个:

$ awk '{ if($0 ~ "I want following letters:") {s=1} else if(!($0 ~ "^X[0-9]*$")) {s=0}; if (s && $0 ~ "^X[0-9]*$") {gsub("X", ""); print}}' data.txt
1
2
3
7
相关问题