6

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.

6

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

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

  • 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 '15 at 13:30
  • 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 '15 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 '15 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 '15 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 '15 at 13:45
0

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

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.