Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Would like to pull the last line of text from a specific (multiple) files in a directory. Additionally, I'd like the results to be in a more traditional column format (like ls) with path, rather than the typical format of tail.

From the following results {1}, I'd like to append as an additional column the last row of data {2}

Where {1} = find . -iname 'updated.txt', and {2} = tail -n1

I'm using bash in Mavericks


2 Answers 2

up vote 0 down vote accepted

Here you go:

find . -iname 'updated.txt' -exec ls -l {} \; -exec tail -n1 {} \;

A simpler alternative but with less control over the formatting of ls:

find . -iname 'updated.txt' -ls -exec tail -n1 {} \;


As you said in comments, you prefer to have the ls output and the tail output side by side for each file.

You could run a subshell for each match to echo the output of the two commands side by side:

find . -iname 'updated.txt' -exec sh -c 'echo $(ls -l "{}") $(tail -n1 "{}")' \;

Similarly, you could use paste:

find . -iname 'updated.txt' -exec bash -c 'paste <(ls -l "{}") <(tail -n1 "{}")' \;

Or you could run the two find commands in parallel and paste their output side by side like this:

paste \
  <(find . -iname 'updated.txt' -exec ls -l {} \;) \
  <(find . -iname 'updated.txt' -exec tail -n1 {} \;)
Is there any way to keep all the results on the same line however? Currently each time tail runs, it places each result on a new line. –  Kris Dec 30 '13 at 14:00
You want first a listing of ls -l, one line per file, plus at the end one more line with the content of the last lines pasted together like columns, like that? –  janos Dec 30 '13 at 15:04
All inline: I'd like tail to be appended to ls -l as an additional column rather than have tail add a newline. –  Kris Dec 30 '13 at 15:59
The first two options have issues encountering spaces in the result set. <br/> <br/> The last option worked though. Could you explain how it functions? <br/> paste \ <br/> <(find . -iname 'updated.txt' -exec ls -l {} \;) \ <br/> <(find . -iname 'updated.txt' -exec tail -n1 {} \;) –  Kris Dec 30 '13 at 20:49
True, I fixed the issues with spaces. The <(...) in paste <(cmd1) <(cmd2) is called Process Substitution. The idea is replacing <(...) with a named pipe, which contains the output of the commands inside. You can read about it in man bash under the Process Substitution section. –  janos Dec 30 '13 at 21:03
$ find . -iname 'updated.txt' -printf '%M %u %g %s %Tc %p\t' -exec tail -n1 {} \;

Output will be like:

-rw-r--r-- user group 4853 2013-12-22T00:58:32 MSK ./path/updated.txt    Last line of the updated.txt.
And why downvoted, may I ask? –  Dmitry Alexandrov Dec 30 '13 at 17:02
One thing to note is that this won't work out of the bag on Mac: printf isn't supported in find. After installing findutils it works like a champ. Thanks for the help. –  Kris Dec 30 '13 at 20:26
@Kris You’re welcome. :) As for me, now I know that ‘Mavericks’ is OS X release (yes, it was worth mentioning). –  Dmitry Alexandrov Dec 30 '13 at 20:41
@DmitryAlexandrov yeah I wish downvoters commented but they don't always do :( It's a nice answer +1 –  janos Dec 30 '13 at 21:05

This site is currently not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .