我正在编写一个脚本,我想检查文件的第一行是否匹配某个模式,如果匹配则打印出该文件。我怎样才能实现这个目标?
如何检查模式?有没有办法检查模式并根据输出做一些事情..
编辑:请看一下这个问题: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 也应该可以通过小任务轻松管理。