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

share|improve this question
add comment

2 Answers

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 {} \;

UPDATE

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 {} \;)
share|improve this answer
    
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
add comment
$ 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.
share|improve this answer
    
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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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