多行正则表达式(grep、sed、awk、perl)

Mik*_*yth 5 grep sed awk regular-expression

我知道多行正则表达式已经讨论了几十次,但我无法让它与我的模式一起工作。

我会试着解释一下。我在一个目录中有一些文本文件。文件中的文本示例:

LINE OF TEXT 2
LINE OF TEXT 1
LINE OF TEXT 3

LINE OF TEXT 1
LINE OF TEXT 2
LINE OF TEXT 3

LINE OF TEXT 1
LINE OF TEXT 3

LINE OF TEXT 3
LINE OF TEXT 2
LINE OF TEXT 1

LINE OF TEXT 2
LINE OF TEXT 3
Run Code Online (Sandbox Code Playgroud)

我想找到在“LINE OF TEXT 2”之后的“LINE OF TEXT 3”,而后者又出现在“LINE OF TEXT 1”之后(中间没有空行)。

每行必须是一个正则表达式本身,例如一行以“LINE”开头并以特定数字结尾。

注意:并非所有文件都包含该确切的行序列,因此如果模式匹配,则不要打印模式,而只是将文件名打印到 STDOUT。

这可以在单行正则表达式中完成吗?因此,例如,awk 在文件中搜索模式,如果找到模式,则将文件名打印到 STDOUT。然后我可以将此正则表达式与“find -exec”结合使用。

任何提到的工具都可以使用(grep、awk、sed 或 perl)。

Wil*_*ard 4

您可以使用 Awk 通过将“记录分隔符”变量设置为匹配至少两个连续换行符的正则表达式来执行此操作:

awk -v RS='\n\n+' '/1.*2.*3/' file.txt
Run Code Online (Sandbox Code Playgroud)

您还可以将“字段分隔符”设置为单个换行符:

awk -v RS='\n\n+' -F '\n' '$1 == "LINE OF TEXT 1" && $2 == "LINE OF TEXT 2" && $3 == "LINE OF TEXT 3"' file.txt
Run Code Online (Sandbox Code Playgroud)

为了便于阅读而进行了分解:

awk -v RS='\n\n+' -F '\n' '
  $1 == "LINE OF TEXT 1" &&
  $2 == "LINE OF TEXT 2" &&
  $3 == "LINE OF TEXT 3"
' file.txt
Run Code Online (Sandbox Code Playgroud)

如果您要求仅在找到匹配项时打印文件名,您可以这样做:

awk -v RS='\n\n+' -F '\n' '
  $1 == "LINE OF TEXT 1" &&
  $2 == "LINE OF TEXT 2" &&
  $3 == "LINE OF TEXT 3" {
    match++
  }
  END {
    if (match) {
      print FILENAME
    }
' file.txt
Run Code Online (Sandbox Code Playgroud)

但考虑到您正在谈论与 结合使用findawk,我建议仅使用 Awk 作为退出状态并用于find打印:

find . -type f -exec awk -v RS='\n\n+' -F '\n' '
  $1 ~ /LINE OF TEXT 1/ &&
  $2 ~ /LINE OF TEXT 2/ &&
  $3 ~ /LINE OF TEXT 3/ {
    exit 0
  }
  END { exit 1 }
' {} \; -print
Run Code Online (Sandbox Code Playgroud)

这样,如果您想在打印之前执行其他操作(其他一些find主要操作),您就已经做好了准备。