LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (http://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   cp command omitting directories (http://www.linuxquestions.org/questions/linux-newbie-8/cp-command-omitting-directories-669109/)

nanda22 09-11-2008 01:43 AM

cp command omitting directories
 
Hi
I'm using the follwoing command to copy some files from one folder to another, while doing this, i'm getting the following error:
Code:


>find /home/susee/data/A/*/C/ -type f  -name "*.254" | xargs -i cp "{}" /home/susee/databkp/A/*/C/
cp: omitting directory `/home/susee/databkp/A/1/C/'
cp: omitting directory `/home/susee/databkp/A/2/C/'
cp: omitting directory `/home/susee/databkp/A/3/C/'
cp: omitting directory `/home/susee/databkp/A/4/C/'

Please tell me where i've done mistake.

But the same thing when i'm trying without using wild character its working.

Code:

>find /home/susee/data/A/1/C/ -type f  -name "*.254" | xargs -i cp "{}" /home/susee/databkp/A/1/C/

Nylex 09-11-2008 01:45 AM

You use cp's -R option to copy directories recursively, as it says in the man page.

Mr. C. 09-11-2008 02:26 AM

The wildcard is being expanded before the command line is executed. This yields multiple directory targets as arguments. The cp command can only copy to a single directory at a time. You'd need multiple cp commands to do what you want. You can do this in a shell loop.

jschiwal 09-11-2008 02:39 AM

Happy birthday Nylex!

Nylex 09-11-2008 05:03 AM

Quote:

Originally Posted by jschiwal (Post 3276778)
Happy birthday Nylex!

Ta jschiwal!

nanda22 09-11-2008 05:08 AM

i tried with -r,this time, its not showing any error, but still the required files couldn't get copied.

RMLinux 09-11-2008 05:09 AM

Quote:

Originally Posted by nanda22 (Post 3276737)
Hi
I'm using the follwoing command to copy some files from one folder to another, while doing this, i'm getting the following error:
Code:


>find /home/susee/data/A/*/C/ -type f  -name "*.254" | xargs -i cp "{}" /home/susee/databkp/A/*/C/
cp: omitting directory `/home/susee/databkp/A/1/C/'
cp: omitting directory `/home/susee/databkp/A/2/C/'
cp: omitting directory `/home/susee/databkp/A/3/C/'
cp: omitting directory `/home/susee/databkp/A/4/C/'

Please tell me where i've done mistake.

But the same thing when i'm trying without using wild character its working.

Code:

>find /home/susee/data/A/1/C/ -type f  -name "*.254" | xargs -i cp "{}" /home/susee/databkp/A/1/C/

i think the "-name" should be change to "-iname" can you try?
-prune ... read "man find".

jschiwal 09-11-2008 05:25 AM

It would probably be better to use a loop.
Code:

for dir in /home/susee/databkp/A/*/C/
do
  cp "$dir"* "${dir/data/datadkp}"
done

It may be easier to see what you are doing if you do it like:
Code:

for dir in 1 2 3 4; do
cp /home/susee/data/A/$dir/C/*.254 /home/susee/datadkp/$dir/C/
done

Thiis assumes that the target directories exist. If not, you can run::
Code:

mkdir -p /home/susee/datadkp/{1..4}/C

One trick is to precede a cp or mv command with "echo" to print out what command would be executed. If it looks good, hit the up arrow and remove the echo.

nanda22 09-11-2008 11:18 PM

Quote:

Originally Posted by RMLinux (Post 3276905)
i think the "-name" should be change to "-iname" can you try?
-prune ... read "man find".

"-iname" didnt't work

nanda22 09-12-2008 01:21 AM

Quote:

Originally Posted by jschiwal (Post 3276919)
It would probably be better to use a loop.
Code:

for dir in /home/susee/databkp/A/*/C/
do
  cp "$dir"* "${dir/data/datadkp}"
done

It may be easier to see what you are doing if you do it like:
Code:

for dir in 1 2 3 4; do
cp /home/susee/data/A/$dir/C/*.254 /home/susee/datadkp/$dir/C/
done

Thiis assumes that the target directories exist. If not, you can run::
Code:

mkdir -p /home/susee/datadkp/{1..4}/C

One trick is to precede a cp or mv command with "echo" to print out what command would be executed. If it looks good, hit the up arrow and remove the echo.

thank you sir, its working fine. but can you please explain it clearly interms of source directory and destination deirectory, because my source and destination files are at different locations, not at the same "/home/susee" path.

source dir: /home/susee/data
destination dir : /home/rhl/databkp

can you please explain the same with above dirs.

and going for other option
Code:

for dir in 1 2 3 4....
its very difficult for me becasue there are more than 300 possible files

thanks in advance

chrism01 09-12-2008 01:45 AM

Use 'seq' cmd to generate a sequential num list: http://tldp.org/LDP/abs/html/abs-guide.html#EX53

Mr. C. 09-12-2008 01:45 AM

It will be helpful to you if you understand how and when the shell expands the * wildcard.

When you create a command line such as:

Code:

ls /path/*/stuff
the shell replaces the * with all possible path components that exist under the directory /path and that also have a directory or file named stuff. This is done before the shell actually runs the command. So if the following existed:

/path/1/stuff
/path/2/stuff/anything
/path/3/stuff/morestuff

/path/4/nostuff

the shell would expand the * into only the first three items (marked in blue), but not the fourth item (marked in red). The command the shell would actually execute would be:

Code:

ls /path/1/stuff /path/2/stuff/anything /path/3/stuff/morestuff
The ls command sees 3 command line arguments. It never sees the * that you typed.

The for loop in jschiwal's response:

Code:

for dir in /home/susee/databkp/A/*/C/
works in exactly the same way; the shell expands the * wildcard, so (assuming the sub-directories named XXX, YYY, and ZZZ) the command is expanded (globbed) to become:

Code:

for dir in /home/susee/databkp/A/XXX/C/ /home/susee/databkp/A/YYY/C/ /home/susee/databkp/A/ZZZ/C/
Again, the for loop never sees the * wildcard.

The problem with your original find command is that you were providing the cp command with too many destination directories. Your command looked essentially like this:

Code:

cp source_files targetDir1 targetDir2 ... targetDirN
and cp only supports copying to a single target directory. To copy to multiple target directories, you must run the cp command multiple times, each time copying to one of your target directories.

This is where the loop comes in handy. You copy many source files into one directory, and do it again to the next, etc.

Now, your job is to explain what your source paths look like and what your target directories look like. This will help you see the pattern required to create a loop. The code provided to you assumes a simple pattern of names ranging from 1 to 4.

nanda22 09-12-2008 02:38 AM

Dear Mr C,
thanks lot for your outstanding explanation.

I've source files at /home/susee/data/network/station/channel/file1 file2 file3 file4......
and destination files at /home/rhl/databkp/network/station/channel/file1 file2 file3......

let us assume file4 is generated today, at the end of the day, i want to copy this file4 from source to destination dir.
The "network" is variable, which has values like... A, B, C ,D.... upto some 30
In each network we've it's corresponding station files... like network A contains, A1,A2,A3,A4
network B contains, B1,B2
network C contains, C1,C2,C3,C4,C5,C6

like this we've around 300 station files (from all networks)

channel type varies channel1, channel2, channel3 for every station.
in that everyday one new file comes.
so what i was tyring is, take backup of each file at the end of everyday.

i used "for loop" for network variable as it has only 30 values.
But Coudn't that go with station, bcoz it has aroud 300 values.

this is why i used wild character instead using name.

i hope u understood the problem.

Mr. C. 09-12-2008 10:40 AM

Let's step back a moment. Do you know about rsync ?

nanda22 09-12-2008 11:12 PM

no,i dont about this "rsync" command


All times are GMT -5. The time now is 01:26 AM.