How can I find the newest file in a directory that contains a certain string?

21,355

Solution 1

ls -1rt /path/to/files/ | tail -n1 will find the newest file in a directory (in terms of modification time); pass that as an argument to grep:

grep 'string to find' "$(ls -1rt /path/to/files/ | tail -n1)"

Solution 2

Here is a version that is safe for names with whitespace:

find /var/log/folder -type f -printf '%T@ %p\0' | sort -rz | sed -Ezn '1s/[^ ]* //p' | xargs --null grep string

How it works:

  • find /var/log/folder -type f -printf '%T@ %p\0'

    This looks for files and prints their modification time (seconds) followed by a space and their name followed by a nul character.

  • sort -rz

    This sorts the null-separated data.

  • sed -Ezn '1s/[^ ]* //p'

    sed -z handles nul-character delimited lines and this prints just the name of the newest file

  • xargs --null grep string

    This reads the null-separated file name and greps the string.

Share:
21,355

Related videos on Youtube

user53029
Author by

user53029

Updated on September 18, 2022

Comments

  • user53029
    user53029 almost 2 years

    I have a need to search a certain folder for the newest created file and grep the contents for a pattern. I have had ok success so far using this command:

    find /var/log/folder -type f -printf '%T+ %p\n' | sort | tail -n1 | xargs grep 'string to find'
    

    This does find the latest file that has the match but I am getting an unexpected line in stdout.

    $ find /var/log/folder -type f -printf '%T+ %p\n' |   sort | tail -n1 | xargs grep 'string to find'
    grep: 2016-05-12+20:01:59.0570667340: No such file or directory
    /var/log/folder/file:string to find
    

    How can I change my command so it does not give me the "no such file or directory" line?

  • user53029
    user53029 about 8 years
    using -1art was returning "grep: .: Is a directory". I changed it to "ls -Art" and it works perfectly. So why was ls -1art was not working as expected?
  • G-Man Says 'Reinstate Monica'
    G-Man Says 'Reinstate Monica' about 8 years
    @DopeGhoti: You find that ls dir and ls dir/ do different things?  Not for me.
  • Pankaj Goyal
    Pankaj Goyal about 8 years
    I do when I'm sleep-deprived and actually thinking of rsync and not ls. The problem was that I had -a in my answer which was including . and .., which might end up being the most recently changed thing in a directory.
  • Alessio
    Alessio about 8 years
    GNU ls really needs a -0 or other NUL-delimiter option, like many other GNU tools (including head and tail) have gained over the last decade or so....it's starting to become surprising when you find a GNU tool that doesn't have one yet.
  • Alessio
    Alessio about 8 years
    You can exclude directories with ls's -p option (which appends a '/' to directory names) and piping into grep -v '/$' before piping into tail -n 1. This works with at least GNU and FreeBSD's versions of ls.
  • don_crissti
    don_crissti about 8 years
    @cas - that will probably never happen (and for good reason imo).
  • John1024
    John1024 about 8 years
    It still would be nice to have a tool that offered ease of use, like ls or ls -rt, but that you could count on to work reliably with modern file names.