如何找到包含特定模式的文件在特定行号上?假设我有一个目录,其中包含一堆包含 3 行的文本文件,例如:
Title A
Category X
Description Y
如何 grep/过滤每个在线Category X
文件2
?如何找到包含Title A
as 行的文件1
?
我查看了 grep 手册页、ripgrep 和替代方案,但不确定是否可以将模式搜索限制为特定行号。
答案1
你可以awk
这样使用:
awk 'FNR == 2 && /Category X/ {print FILENAME}' *
答案2
当在第二行中找到模式时,您可以使用find
withawk
来退出处理文件的其余部分,或者如果在第二行中没有找到模式,也可以退出。
find -type f -name 'xyz*.txt' -exec \
awk 'NR==2{ if(/pattern/) print FILENANE; exit }' {} \;
答案3
grep
只是为了好玩:
PAT="Category X"
LN=2
> grep -n "$PAT" file* | grep ":$LN:$PAT$" | grep -o "^[^:]*"
file1
file2
答案4
GNU grep 可用于您的用例:
$ grep -Plzr '^(?:.*\n){1}.*Category X' .
grep
通常在每行的基础上工作,但 GNU grep 添加了一个-z
选项,它将整个文件视为一行,因为它分隔在文本文件中找不到的字符 ( \0
) 上的记录。
现在我们可以将正则表达式应用于整个文件。您的要求是仅搜索第二行,因此我们不做任何事情就驶过一行^(?:.*\n){1}
插入符号 ^ 将正则表达式锚定为从头开始。该点不能跨行,因为它与换行符不匹配。
然后.*Category X
将开始查找下一行,即第二行,但不会跨行,因此如果在第二行找到模式则匹配。
如果存在匹配,该-l
选项会将文件名列出到 STDOUT。
该-r
选项将使 grep 递归运行(GNU 功能)。
将-P
能够编写 Perl 风格的正则表达式(GNU 功能)。
这是使用 GNU find+sed 组合解决该问题的另一个方法:
$ find . -type f -exec sed -ns '2{/Category X/F;}' {} +
GNU find + GNU xargs 输入 Perl 也可以做到这一点:
find . -type f ! -size 0 -print0 |
xargs -r0 perl -lne '
(eof||$.==2)&&do{
print $ARGV if $.==2 && /Category X/;
close ARGV; undef $.;
};
'