Finding the most recent file with a conditional string

When you say "the most recent", do you mean the most recently modified?

If you just want to know, interactively:

cd documents/
/bin/ls -t1 $(grep -Fl pass *.txt) | head -n 1
  • grep -Fl lists files containing the string pass, excluding the actual matching lines.
  • ls -t lists those files in order of modification time. Change -t to -tc for status change time, or -tu for access time.
  • Using a command sub like this is brittle, if the filenames contain spaces or shell meta characters.
  • But this is probably the most portable way. You can do IFS=$'\n' and set -f first, to make it less brittle.

On Linux, a more robust version is the following. Suitable for scripts, but not portable, because stat is not POSIX:

#!/bin/sh

cd /path/to/documents/

mapfile -t matching < <(grep -Fl pass *.txt)

stat -c '%n %Y' -- "${matching[@]}" |
sort -n -t ' ' -k 2 |
tail -n 1 |
cut -d ' ' -f 1

A slightly more robust thing to do is to use null instead of new line delimiters, if the file names may contain new lines (eg. are unknown). These are all GNU options:

mapfile -td '' matching < <(grep -FZl pass *.txt)

stat --printf '%n %Y\0' -- "${matching[@]}" |
sort -zn -t ' ' -k 2 |
tail -zn 1 |
cut -d ' ' -f 1
/r/bash Thread