52

I have a working grep command that selects files meeting a certain condition. How can I take the selected files from the grep command and pipe it into a cp command?

The following attempts have failed on the cp end:

grep -r "TWL" --exclude=*.csv* | cp ~/data/lidar/tmp-ajp2/ 

cp: missing destination file operand after ‘/home/ubuntu/data/lidar/tmp-ajp2/’ Try 'cp --help' for more information.


cp `grep -r "TWL" --exclude=*.csv*` ~/data/lidar/tmp-ajp2/ 

cp: invalid option -- '7'

1

5 Answers 5

73
grep -l -r "TWL" --exclude=*.csv* | xargs cp -t ~/data/lidar/tmp-ajp2/ 

Explanation:

  • grep -l option to output file names only
  • xargs to convert file list from the standard input to command line arguments
  • cp -t option to specify target directory (and avoid using placeholders)
Sign up to request clarification or add additional context in comments.

5 Comments

The -l option does not work for me. Aside from that, it works fine.
-t is said an illegal option for cp on macOS sierra.
I still had issues with cp using this syntax. Chris Maes solution below worked for me
Had issues with this answer where the filenames contained spaces.
Is there a way to use this solution if the file name length is too long for cp?
44

you need xargs with the placeholder option:

grep -rl "TWL" --exclude=*.csv* | xargs -I '{}' cp '{}' ~/data/lidar/tmp-ajp2/ 

normally if you use xargs, it will put the output after the command, with the placeholder ('{}' in this case), you can choose the location where it is inserted, even multiple times.

2 Comments

Your answer worked nearly perfectly, yet grep -r raised an error since it passed the entire result (with the line containing the string) to xargs. This issue was solved using with both rl flags, as in: grep -rl '<search_string>' * | xargs -I '{}' cp '{}' <detination_dir>
@RonyArmon you are completely right. It's a mystery to my why you are the first one to point this error. Thanks.
9

This worked for me when searching for files with a specific date:

 ls | grep '2018-08-22' | xargs -I '{}' cp '{}' ~/data/lidar/tmp-ajp2/ 

2 Comments

please explain xargs -I '{}' cp '{}' ~/data/lidar/tmp-ajp2/
@santosh-kumar, the '{}' are placeholders for the results of the grep listing ls | grep. So in my case, the command listed all the files that match the given date in their filename, and then copied each file to a specific directory.
1

To copy files to grep found directories, use -printf to output directories and -i to place the command argument from xarg (after pipe)

find ./ -name 'filename.*' -print '%h\n' | xargs -i cp copyFile.txt {} 

this copies copyFile.txt to all directories (in ./) containing "filename"

Comments

-1

grep -rl '/directory/' -e 'pattern' | xargs cp -t /directory

1 Comment

Would you care to elaborate on that?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.