11

I am trying to do something like

ls -t | head -n 3 | xargs -I {} tar -cf t.tar {}

to archive the 3 last modified files but it ends up running the tar command separately for each of the files and at the end I am left with one tar file containing the last of the 3 files (in their whatever order). I know I am not using 'xargs' correctly but searching did not help; I find examples that do not work either. Even the simpler command

ls | xargs -I {} tar -cf t.tar {}

ends up with a tar file that contains only one of the files in that directory.

2 Answers 2

9

ls -t | head -n 3 | xargs tar -cf t.tar

Works for me. Is there a reason you need the -I flag set?

5
  • It never occurred to me to try that; thank you so much! But what if I really wanted to pass them with -I? Is there a way to format it correctly that way?
    – oligilo
    Nov 20, 2015 at 13:30
  • 1
    If you want to use the -I flag then you should use something other than {} for the replacestring. For example ls -t | head -n 3 | xargs -I foo tar -cf t.tar foo
    – David King
    Nov 20, 2015 at 13:33
  • I did, but I am getting the same result: only the last file or, equivalently, it runs the tar command separately for each item.
    – oligilo
    Nov 20, 2015 at 13:37
  • After further reading in the xargs man page...-I implies -L 1 which effectively means run the following command for each 1 line of input which is why you're seeing the results you are.
    – David King
    Nov 20, 2015 at 13:41
  • Ah, I see; thank you so much for your help; it was bugging me for days. I really appreciate it.
    – oligilo
    Nov 20, 2015 at 13:45
1

According to this post, it's better to use r instead of c, in case xargs chops up the inputs, yielding a tar file containing only the last chunk. So a better solution would be:

rm -f t.tar 2>/dev/null  # remove tar if there
ls -t | head -n 3 | xargs tar -rf t.tar

You must log in to answer this question.

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