LinuxQuestions.org
Support LQ: Use code LQ3 and save $3 on Domain Registration
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 07-01-2013, 02:24 AM   #1
babhijit
LQ Newbie
 
Registered: May 2013
Posts: 6

Rep: Reputation: Disabled
how to use cp find and grep together to copy a list of files using find with grep


I am getting a list of files using the following command:

find . type -f | xargs grep -l 19201020320

now I want to modify the above command so that the listing produced by the above command can be copied to a folder (say /tmp).

Tried the following but did not work!

find . type -f | xargs grep -l 19201020320 | xargs cp /tmp

Got the error message:
cp: copying multiple files, but last argument `./XYZ.20130701.060000' is not a directory
Try `cp --help' for more information.

Last edited by babhijit; 07-01-2013 at 02:41 AM.
 
Old 07-01-2013, 02:59 AM   #2
mddnix
Member
 
Registered: Mar 2013
Location: Bangalore, India
Distribution: Redhat, Arch, Ubuntu
Posts: 512

Rep: Reputation: 139Reputation: 139
Code:
find . -type f -name "*19201020320*" -exec cp '{}' /tmp \;
 
Old 07-01-2013, 03:28 AM   #3
babhijit
LQ Newbie
 
Registered: May 2013
Posts: 6

Original Poster
Rep: Reputation: Disabled
My criteria is searching in files for a given string .. in this case "19201020320". Shouldn't -name in find search for files having file names "*19201020320*"?
 
Old 07-01-2013, 04:33 AM   #4
mddnix
Member
 
Registered: Mar 2013
Location: Bangalore, India
Distribution: Redhat, Arch, Ubuntu
Posts: 512

Rep: Reputation: 139Reputation: 139
Try this:
Code:
#!/bin/bash
for file in $(find . -type f -exec grep -l "19201020320" '{}' +)
do
   cp $file /tmp
done
 
Old 07-01-2013, 04:41 AM   #5
asimba
Member
 
Registered: Mar 2005
Location: 127.0.0.0
Distribution: Red Hat / Fedora
Posts: 355

Rep: Reputation: 42
Try following anf see if it works

Code:
grep -l 19201020320 ./* |  xargs -I {} cp {} ./tmp/
 
1 members found this post helpful.
Old 07-01-2013, 05:26 AM   #6
TobiSGD
Moderator
 
Registered: Dec 2009
Location: Germany
Distribution: Whatever fits the task best
Posts: 17,130
Blog Entries: 2

Rep: Reputation: 4825Reputation: 4825Reputation: 4825Reputation: 4825Reputation: 4825Reputation: 4825Reputation: 4825Reputation: 4825Reputation: 4825Reputation: 4825Reputation: 4825
Quote:
Originally Posted by babhijit View Post
find . type -f | xargs grep -l 19201020320 | xargs cp /tmp
Just to explain why this won't work: xargs will append the input it gets from the pipe to the end of the command, so that you will in your case have the destination directory before the source files, while cp expects it to be the other way around. For cases like these cp has the -t option, which will allow you to specifically name the destination directory. If you change your command to
Code:
find . type -f | xargs grep -l 19201020320 | xargs cp -t /tmp
it should work.
 
2 members found this post helpful.
Old 07-01-2013, 05:27 AM   #7
asimba
Member
 
Registered: Mar 2005
Location: 127.0.0.0
Distribution: Red Hat / Fedora
Posts: 355

Rep: Reputation: 42
I am unsure as why find command is being used - Is using grep directly inefficient ?
 
Old 07-01-2013, 05:29 AM   #8
babhijit
LQ Newbie
 
Registered: May 2013
Posts: 6

Original Poster
Rep: Reputation: Disabled
Yeap. That's what I was looking for
 
Old 07-01-2013, 05:35 AM   #9
babhijit
LQ Newbie
 
Registered: May 2013
Posts: 6

Original Poster
Rep: Reputation: Disabled
I am a newbie trying to feel around linux .. its more of an issue of getting through things rather than performance :P
 
Old 07-03-2013, 12:43 PM   #10
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
Quote:
Originally Posted by mddesai View Post
Try this:
Code:
#!/bin/bash
for file in $(find . -type f -exec grep -l "19201020320" '{}' +)
do
   cp $file /tmp
done
No, please Don't Read Lines With For! The output of commands should always be processed with a while+read loop, or some other similar technique that allows you to safely delimit the input with null separators.

Always remember to quote your variables too, for similar reasons.

Code:
#!/bin/bash
while IFS='' read -d '' -r fname; do
    cp "$fname" /tmp
done < <( find . -type f -exec grep -lZ "19201020320" '{}' + )
In this particular case, since it's grep doing the actual printing, we need to use its -Z option for null separators, rather than the usual -print0 of find.

Of course we can also use xargs instead of the loop, since it can handle null separated input too.

Code:
find . -type f -exec grep -lZ '19201020320' '{}' + | xargs -0 cp -t /tmp
And actually, find can probably be eliminated as well, since grep can do recursive searching all by itself.

Code:
grep -lZR '19201020320' . | xargs -0 cp -t /tmp
You can also add --include and --exclude options for more exact file filtering if needed. See the man/info pages.

Finally, notice how I used the -t option in cp, to invert the order of the arguments and make the command simpler. I believe this is only available in gnu cp, however.


PS: Please use ***[code][/code]*** tags around your code and data, to preserve the original formatting and to improve readability. Do not use quote tags, bolding, colors, "start/end" lines, or other creative techniques. Thanks.
 
2 members found this post helpful.
Old 07-03-2013, 01:25 PM   #11
mddnix
Member
 
Registered: Mar 2013
Location: Bangalore, India
Distribution: Redhat, Arch, Ubuntu
Posts: 512

Rep: Reputation: 139Reputation: 139
@David the H.

Thanks for showing my mistakes. your suggestions were truly insightful. I really appreciate that.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
find, grep and copy based on timestamp rootaccess Linux - General 14 03-20-2013 10:09 PM
[SOLVED] Recursive search for strings in files with a certain date: find -name or grep -R? wolverene13 Linux - Newbie 6 10-01-2011 06:05 PM
Problem Searching for php files with Find and Grep ssmela Linux - General 3 11-02-2010 02:55 PM
Find/grep/wc command to find matching files, print filename and word count dbasch Linux - Newbie 10 09-14-2009 06:55 PM
searching within files. cat grep find w3bd3vil Linux - Newbie 4 10-13-2008 04:59 AM


All times are GMT -5. The time now is 12:56 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration