使用 awk 查找具有特定 2 行模式的文件

Err*_*404 3 command-line bash find awk

我有数百个具有这种模式的文件

@<TRIPOS>ATOM
  2 H18 65.2220 Du 1 RES1 0.0000
@<TRIPOS>BOND
 1  3  5  ar
@<TRIPOS>SUBSTRUCTURE
Run Code Online (Sandbox Code Playgroud)

其中,有些文件缺少 后的行@<TRIPOS>BOND,它们看起来像

@<TRIPOS>ATOM
  2 H18 65.2220 Du 1 RES1 0.0000
@<TRIPOS>BOND
@<TRIPOS>SUBSTRUCTURE
Run Code Online (Sandbox Code Playgroud)

我试图在我的工作目录中找到所有在 之后缺少数字行的文件,@<TRIPOS>BOND并将它们移动到另一个目录。我知道这是一项简单的任务,但我对 Linux 还是很陌生。

注意:文件的长度和行号各不相同,这就是我在@<TRIPOS>BOND字符串后面“grepping”行的原因。

这是我的代码之一,我计划在 for 循环中编写。它不起作用,但我展示它是为了展示我的试验之一。

cat file | grep -A1 '@<TRIPOS>BOND' | awk 'FNR == 2 {print}'
Run Code Online (Sandbox Code Playgroud)

谢谢

ste*_*ver 6

如果您的 grep 版本支持 PCRE 模式 ( -P),您可以尝试多行匹配,以查找@<TRIPOS>BOND其后跟(仅在换行符之后)的实例,@<TRIPOS>SUBSTRUCTURE例如

grep -lzP '\Q@<TRIPOS>BOND\E\n\Q@<TRIPOS>SUBSTRUCTURE\E' *
Run Code Online (Sandbox Code Playgroud)

\Q\E可能是在这种情况下不必要的,但是,为了强制字面匹配(在情况下@><具有在Perl的正则表达式语法特殊的含义)。该-l告诉grep来列出匹配的文件,而不是打印的比赛。然后,您可以使用文件列表作为mv命令的输入,例如

grep -lzP '\Q@<TRIPOS>BOND\E\n\Q@<TRIPOS>SUBSTRUCTURE\E' * | xargs mv -t /path/to/newdir/
Run Code Online (Sandbox Code Playgroud)


附加信息

您可以将比赛的第二部分表示为前瞻,但我认为在这种情况下它没有任何优势

grep -lzP '\Q@<TRIPOS>BOND\E\n(?=\Q@<TRIPOS>SUBSTRUCTURE\E)' *
Run Code Online (Sandbox Code Playgroud)

中的等效表达式pcregrep(它不是标准 Ubuntu 系统的一部分,但可以从存储库中获得)将类似于

pcregrep -lM '\Q@<TRIPOS>BOND\E\n\Q@<TRIPOS>SUBSTRUCTURE\E' *
Run Code Online (Sandbox Code Playgroud)

pcregrep -lM '\Q@<TRIPOS>BOND\E\n(?=\Q@<TRIPOS>SUBSTRUCTURE\E)' *
Run Code Online (Sandbox Code Playgroud)