How to print file content only if the first line matches a certain pattern?
You could do that with ed
:
ed -s infile <<\IN 2>/dev/null
1s/PATTERN/&/
,p
q
IN
the trick here is to try to replace PATTERN
on 1st
line with itself. ed
will error out if it can't find the specified pattern so ,p
(print whole file) will only be executed if 1s/PATTERN/&/
is successful.
Or with sed
:
sed -n '1{
/PATTERN/!q
}
p' infile
this q
uits if the first line does not (!
) match PATTERN
, otherwise it p
rints all lines.
Or, as pointed out by Toby Speight, with GNU sed
:
sed '1{/PATTERN/!Q}' infile
Q
is the same as q
but it does not print the pattern space.
With POSIX tools chest:
{ head -n 1 | grep pattern && cat; } <file
awk '/pattern/{print FILENAME}; {nextfile}' ./*.txt
would print the name of the non-hidden txt
files in the current directory whose first line matches the extended regular expression pattern
with those awk
inplementations that support nextfile
.
If instead of printing the file name, you want to print the whole file content, you can do:
awk 'FNR == 1 && ! /pattern/ {nextfile}; {print}' ./*.txt
That's efficient in that it runs only one command, but awk
being not the most efficient command to dump the content of a file, with large files, you could possibly obtain better performances by doing something like:
awk '/pattern/{printf "%s\0", FILENAME}; {nextfile}' ./*.txt |
xargs -r0 cat
That is, only use awk
to print the list of files that match (0-delimited) and rely on cat
to dump their content.