仅当第一行匹配特定模式时如何打印文件内容?

仅当第一行匹配特定模式时如何打印文件内容?

我正在编写一个脚本,我想检查文件的第一行是否匹配某个模式,如果匹配则打印出该文件。我怎样才能实现这个目标?

如何检查模式?有没有办法检查模式并根据输出做一些事情..

编辑:请看一下这个问题:https://stackoverflow.com/questions/5536018/how-to-get-match-regex-pattern-using-awk-from-file

我想要这样的东西,但它们都不适合我。我基本上想检查第一行是否匹配正则表达式模式,并根据该打印文件行。

答案1

你可以这样做ed

ed -s infile <<\IN 2>/dev/null
1s/PATTERN/&/
,p
q
IN

这里的技巧是尝试PATTERN在线替换1st自身。ed如果找不到指定的模式,则会出错,因此(打印整个文件)只有在成功,p时才会执行。1s/PATTERN/&/

或者与sed

sed -n '1{
/PATTERN/!q
}
p' infile

q如果第一行不 ( !) 匹配PATTERN,则执行此操作,否则将p打印所有行。
或者,正如指出的那样托比·斯佩特,与 GNU sed

sed '1{/PATTERN/!Q}' infile

Q与 相同q,但不打印模式空间。

答案2

带有 POSIX 工具箱:

{ head -n 1 | grep pattern && cat; } <file

答案3

 awk '/pattern/{print FILENAME}; {nextfile}' ./*.txt

txt将打印当前目录中第一行pattern与扩展正则表达式匹配的非隐藏文件的名称那些awk支持的实施nextfile

如果您不想打印文件名,而是想打印整个文件内容,则可以执行以下操作:

 awk 'FNR == 1 && ! /pattern/ {nextfile}; {print}' ./*.txt

这是有效的,因为它只运行一个命令,但awk不是转储文件内容的最有效命令,对于大文件,您可能可以通过执行以下操作来获得更好的性能:

 awk '/pattern/{printf "%s\0", FILENAME}; {nextfile}' ./*.txt |
   xargs -r0 cat

也就是说,仅用于awk打印匹配(0 分隔)的文件列表并依赖cat转储其内容。

答案4

老派,只需将你的句子翻译成标准命令即可:

for file in *; do
    if head -n 1 "${file}" | grep -q 'PATTERN'; then
        cat "${file}"
    fi
done

对于学习 bash 来说这是一个好的开始。如果您只需要快速解决方案,请尝试 sed、awk 或 perl 答案。两者都很好,但它们是您需要(并且可能想要)学习的自己的语言。

这是一个非常简单的示例,因此如果您想了解更多信息,您也可以在 ruby​​、php、js(例如在 Nodejs 中)或任何其他允许文件访问的语言中尝试相同的操作。即使是 C/C++ 或 Java 也应该可以通过小任务轻松管理。

相关内容