2

I feel like I am missing something very simple and I was wondering if it possible to sow the last few lines of the last 4 modified files. I tried something like this

tail | ls -lt | head -5

but I think I should iterate over ls | -lt result and apply tail to it and I am not sure how to do it. Any help is appreciated

4

4 Answers 4

5

Before I start, it’s generally considered bad practice to use the output of ls as input for something else; a common flaw being that it may not work as intended for files containing white space/new line in their name.

With that limitation in mind, you will probably find that ls | something will work OK most of the time.

You are heading in the right direction with your command, here is one solution with the above caveat about ls limitations:

ls -t | head -5 | xargs tail

This will throw a non fatal error if there are subdirectories in your listing.

1
  • My files are have normal names with just periods and underscores. Thanks
    – Morpheus
    Nov 30, 2020 at 9:38
4

In the zsh shell, the four most recently modified regular files in the current directory can be had by the globbing pattern

./*(.Dom[1,4])

... where ./* matches all names in the current directory and the parenthesis modifies the behavior of the matching. The . makes the * match only regular files while D makes it also match hidden names (as with the dotglob shell option enabled in the bash shell). The om orders the resulting list of names by modification timestamp and the [1,4] picks out the first four names.

To call tail on these files:

tail ./*(.Dom[1,4])

From the bash shell:

zsh -c 'tail ./*(.Dom[1,4])'

If you want consider all files in the current directory or anywhere below it, then use

zsh -c 'tail ./**/*(.Dom[1,4])'

The ** pattern works in a similar manner to the same globbing pattern in bash when the globstar shell option is enabled, i.e. it matches down into subdirectories recursively. The D in the glob qualifier would make the ** match into subdirectories with hidden names.

1
  • unfortunately I do not ave access to zsh. As in I can not install zsh as this is not my computer.
    – Morpheus
    Nov 30, 2020 at 8:30
1

May be this will help you

find . -type f -mmin -5 -ls | tail -4

In place of . => add your target directory path

This above command will get you the last modified 5 minutes ago files , if want you can increase your last modified minutes from 5 minutes to your need eg: 15min , 20min , 60min

1

If there's no subdirectories, then this should work, even if the files have spaces in their names. It will however fail if the files have newlines in their names.

ls -1t | head -4 | tr '\n' '\0' | xargs -0 head -10

Unfortunately, it will fail if there is subdirectories. If there is, then this should work

find . -type f -maxdepth 1 -print0 | xargs -0 ls -1t | head -4 | tr '\n' '\0' | xargs -0 head -10

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.