March 2010
M T W T F S S
« Feb    
1234567
891011121314
15161718192021
22232425262728
293031  
96

Categories

Archives

[one-liner]: Copying & Moving Files efficiently with xargs

Background

From time to time I need to move and/or copy a subset of files from one directory to another. I typically would use something like one of these to do the task:

1
2
3
4
5
#-- COPY
find . -type f -ctime -1 | xargs -I {} cp {} /some/other/directory
 
#-- MOVE
find . -type f -ctime -1 | xargs -I {} mv {} /some/other/directory

NOTE: The 1st command finds all the files in the current directory that are less than 24 hours old, and copies them to /some/other/directory. The 2nd command finds all the files in the current directory that are less than 24 hours old, and moves them to /some/other/directory.

But then I realized that by using xargs’ –I switch I was basically limiting xargs to doing a single file at a time. According to xargs’ man page, when you use the –I switch you’re implying the –x switch AND the –L 1 switch. The L switch is what tells xargs how many lines of input to process at a time, so we’re basically telling it to only handle one file at a time. This made no sense. I was unintentially limiting xargs’ ability to optimize the command-line. So I found a better way.

New Approach

By utilizing 2 little used switches (–t | ––target-directory) on cp and mv I could un-tie xargs’ hands.

copy
1
2
3
4
5
# long form
find . -type f -ctime -1 | xargs -0 cp --target-directory=/some/other/directory
 
# short form
find . -type f -ctime -1 | xargs -0 cp -t /some/other/directory
move
1
2
3
4
5
# long form
find . -type f -ctime -1 | xargs -0 mv --target-directory=/some/other/directory
 
# short form
find . -type f -ctime -1 | xargs -0 mv -t /some/other/directory

NOTE: For further details regarding my one-liner blog posts, check out my one-liner style guide primer.

4 comments to [one-liner]: Copying & Moving Files efficiently with xargs

  • you should look into the -exec flag in find

    • Yup know all about find’s -exec switch. The problem with -exec is that it gets called everytime find finds a file. So for example if find finds 10,000 files, it would literally call -exec 10,000 times. This is what I was trying to avoid by leveraging xargs. By using xargs you in effect are minimizing the number of times you’ll be calling the body of what gets called in the -exec argument to find.

  • Rodrigo

    find . -type f -ctime -1 | xargs cp -t /some/other/directory

    theres a problem with that command wich is revealed if you try to copy files with spaces in their names, just add -0 option to xargs

    find . -type f -ctime -1 | xargs -0 cp -t /some/other/directory

    • That’s a terrific point. Thanks for bringing it up. I’ve gotten out of the habit of using spaces in files & directories but if you run this on a filesystem that does have files with spaces and/or a directory that may include files from a windows system then odds are you may run into files with spaces. Thanks!

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>