0

I'm trying to search through a set of text files and return the names of files that on a specified line contain a text pattern OR do not contain the text on the specified. In my case I need to return the filenames of files whose last line does not contain the text pattern.

file1.txt

line1 abc
line2 must have

file2.txt

line1 must have
line2 return me

the function/command, when passed "must have", should return ONLY file2.txt, because it does not contain "must have" on the last line.

  • I think instead of 'specified line' you want to say 'last line', throughout? – Jeff Schaller Dec 20 '18 at 20:39
1

To check the contents of the last line of each file in the current directory, use tail and grep:

for file in *.txt
do
  tail -1 -- "$file" | grep -q "must have" || printf '%s\n' "$file"
done

This assumes your text files are named ending with .txt; adjust that wildcard as needed. The tail -1 grabs the last line of the file (seeking backwards, which is more efficient than potentially reading forwards through the file); that line is then piped to grep to look for the desired text. The -q flag to grep tells it to be quiet about its work, and simply set the return code accordingly. If grep does not find a match, then the || "or" alternation tells the shell to execute printf, which prints the filename.

You could put that code in a script or in a function:

lastlinehas() {
  for file in *.txt
  do
    tail -1 -- "$file" | grep -q "$1" || printf '%s\n' "$file"
  done
}
0

Using GNU awk:

$ awk 'ENDFILE { if ($0 !~ /must have/) print FILENAME }' file2.txt file1.txt
file2.txt

This uses a ENDFILE block to test the current contents of $0 (the last line of the file that we just reached the end of) against the regular expression must have. If there is no match, the filename is printed.

The ENDFILE block is not available in BSD awk or mawk.

Using standard awk:

for fname in *.txt; do
    awk 'END { if ($0 !~ /must have/) print FILENAME }' "$fname"
done

This works similarly as the GNU awk solution, but invokes awk once for each file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.