How to copy a directory without specific files?


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting How to copy a directory without specific files?
# 8  
Old 07-28-2014
Quote:
Originally Posted by bakunin
True - my bad. My only excuse is one shouldn't answer threads before the second coffee.

Code:
cd /path/to/sourcedir
find . -type f ! -name "*.[wW][mM][vV]" -exec cp {} /path/to/targetdir \;

This will probably not work either, because now the directory hierarchy will not become copied and some files (the one in sub-subdirectories) will have no proper targets. I suggest to do it in a two-pass way:

Code:
cd /path/to/sourcedir
find . -type d  -exec mkdir -p /path/to/targetdir{} \;
find . -type f ! -name "*.[wW][mM][vV]" -exec cp {} /path/to/targetdir +

The first pass creates a copy of the directory structure, the second copies all the files. If you need to copy filemodes, ownerships, etc. too, you need to modify the "cp"-command accordingly: "cp -p ...".

@Chubler_XL: using "tar" for that was my first impulse, but it would limit the solution to a system where the GNU-tar is available.

I hope this helps.

bakunin
We both needed something before we replied to this thread. I noticed that you hadn't included -type f and then posted a fix that had its own problems. And fixed it, and fixed it again, and fixed it again in a period of about 10 minutes. And, unfortunately, I can't use lack of coffee as an excuse. (I have a caffeine allergy, so I never drink coffee.)

And, I don't think:
Code:
cd /path/to/sourcedir
find . -type d  -exec mkdir -p /path/to/targetdir{} \;
find . -type f ! -name "*.[wW][mM][vV]" -exec cp {} /path/to/targetdir +

does what you were thinking either. The first find does copy the directory hierarchy under sourcedir to targetdir, but the second find still copies all of the non-.wmv files to the targetdir directory; not to their corresponding places in the newly created hierarchy. And, find -exec command + can only be used when there is no more than one {} in the command, and, if there is one, it has to be the last operand in that command.

The OP's desired destination for the copied files seems ambiguous to me. I don't know if the intent is to duplicate the file hierarchy or if the intent is to flatten the file hierarchy into the single directory named as targetdir.

If the intention is to flatten the hierarchy, I still believe:
Code:
cd /path/to/sourcedir
find . -type f ! -name "*.[wW][mM][vV]" -exec cp {} /path/to/targetdir \;

is sufficient.

The the intention is to preserve the hierarchy, I believe we would need something like:
Code:
cd /path/to/sourcedir
find . -type d  -exec mkdir -p /path/to/targetdir{} \;
find . -type f ! -name "*.[wW][mM][vV]" -exec cp {} /path/to/targetdir{} \;

I believe this could be combined into a single find command to avoid walking the tree twice, but with the thousands of invocations of cp the additional complexity might overshadow any performance gain:
Code:
cd /path/to/sourcedir
find . \( -type d  -exec mkdir -p /path/to/targetdir{} \; \) -o \
       \( -type f ! -name '*.[wW][mM][vV]' -exec cp {} /path/to/targetdir{} \; \)

Are we having fun yet???
# 9  
Old 07-28-2014
Quote:
Originally Posted by Don Cragun
We both needed something before we replied to this thread. I noticed that you hadn't included -type f and then posted a fix that had its own problems. And fixed it, and fixed it again, and fixed it again in a period of about 10 minutes. And, unfortunately, I can't use lack of coffee as an excuse. (I have a caffeine allergy, so I never drink coffee.)
Like i can't in this case. Somehow this thread is bringing up the worst in us both. You are right in your assessment

Quote:
Originally Posted by Don Cragun
And, I don't think:
Code:
cd /path/to/sourcedir
find . -type d  -exec mkdir -p /path/to/targetdir{} \;
find . -type f ! -name "*.[wW][mM][vV]" -exec cp {} /path/to/targetdir +

does what you were thinking either. The first find does copy the directory hierarchy under sourcedir to targetdir, but the second find still copies all of the non-.wmv files to the targetdir directory; not to their corresponding places in the newly created hierarchy.
Quote:
Originally Posted by Don Cragun
The the intention is to preserve the hierarchy, I believe we would need something like:
Code:
cd /path/to/sourcedir
find . -type d  -exec mkdir -p /path/to/targetdir{} \;
find . -type f ! -name "*.[wW][mM][vV]" -exec cp {} /path/to/targetdir{} \;

Alas, this is not the case either, because "{}" can only be used once in a command.

Quote:
Originally Posted by Don Cragun
Are we having fun yet???
Yes, we do. Here is my next suggestion. By now i am quite sure it will not do what i want, neither do what the thread-o/p wants and most probably be forbidden by law.

Code:
cd /path/to/sourcedir
find . -type d -exec mkdir -p /path/to/targetdir{} \;
find . -type f ! -name "*.[Ww][Mm][Vv]" -exec FNAME={} ; cp "$FNAME" "/path/to/targetdir$FNAME" \;

Aren't we a happy lot?

bakunin
# 10  
Old 07-28-2014
Quote:
Originally Posted by bakunin
@Chubler_XL: using "tar" for that was my first impulse, but it would limit the solution to a system where the GNU-tar is available.
On systems without GNU-tar I'd be tempted to use cpio.

Code:
cd /path/to/sourcedir
find . -depth ! -name "*.[Ww][Mm][Vv]" |  cpio -pdm /path/to/target


Last edited by Chubler_XL; 07-28-2014 at 05:09 PM..
These 3 Users Gave Thanks to Chubler_XL For This Post:
# 11  
Old 07-28-2014
Quote:
Originally Posted by bakunin
Alas, this is not the case either, because "{}" can only be used once in a command.
Why not? It appears to work.
# 12  
Old 07-28-2014
My man on find says
Quote:
The string ‘{}’ is replaced by the current file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find.
From that I would take it that supporting multipe {} could be a GNU extension.
This User Gave Thanks to Chubler_XL For This Post:
# 13  
Old 07-28-2014
Quote:
Originally Posted by Chubler_XL
My man on find says

From that I would take it that supporting multipe {} could be a GNU extension.
With -exec ... +, {} is only required to be replaced by the current pathname if it is the last argument before the + and only if it is a separate argument.

With -exec ... \;, {} is required to be replaced by the current pathname every time it appears as a separate argument. As an extension to the standards, many implementations replace {} with the current pathname no matter where it occurs in an argument (beginning, middle, end of an argument as well as when it is a stand-alone argument). The standards say the behavior is unspecified if {} appears anywhere other than as a stand-alone argument.

On OS/X, the command:
Code:
find . -type f ! -name "*.[wW][mM][vV]" -exec cp {} /path/to/targetdir/{} \;

works, but (obviously) it isn't portable.
# 14  
Old 07-29-2014
Quote:
Originally Posted by Chubler_XL
On systems without GNU-tar I'd be tempted to use cpio.
True! find ... | cpio -pd ... would perhaps be the most portable and elegant solution to this. What a shame i haven't even thought of that. Thanks for reminding me that there are alternatives to tar.

bakunin
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Copy Specific Files Recursively

Is it possible to only copy selected files+its directories when you are copying recursively? find /OriginalFolder/* -type -d \{ -mtime 1 -o -mtime 2 \ } -exec cp -R {} /CopyTo/'hostname'__CopyTo/ \; -print From the above line, I want to only copy *txt and *ini files from /OriginalFolder/* ... (4 Replies)
Discussion started by: apacheLinux
4 Replies

2. Shell Programming and Scripting

Rsync to copy specific subfolders and files to new directory

RootFolderI: RootFolderI/FolderA/Subfolder1/Subsub1/JPG1.jpg -> want this jpg RootFolderI/FolderA/Subfolder2/Subsub1/JPG2.jpg -> want this jpg RootFolderI/FolderA/Subfolder2/Subsub2/JPG3.jpg . . . RootFolderI/FolderB/Subfolder1/Subsub1/JPG4.jpg -> want this jpg ... (1 Reply)
Discussion started by: blocnt
1 Replies

3. Shell Programming and Scripting

Delete all files if another files in the same directory has a matching occurrence of a specific word

he following are the files available in my directory RSK_123_20141113_031500.txt RSK_123_20141113_081500.txt RSK_126_20141113_041500.txt RSK_126_20141113_081800.txt RSK_128_20141113_091600.txt Here, "RSK" is file prefix and 123 is a code name and rest is just timestamp of the file when its... (7 Replies)
Discussion started by: kridhick
7 Replies

4. Shell Programming and Scripting

Copy the files in directory and sub folders as it is to another directory.

How to copy files from one directory to another directory with the subfolders copied. If i have folder1/sub1/sub2/* it needs to copy files to folder2/sub1/sub2/*. I do not want to create sub folders in folder2. Can copy command create them automatically? I tried cp -a and cp -R but did... (4 Replies)
Discussion started by: santosh2626
4 Replies

5. Red Hat

Unable to copy files due to many files in directory

I have directory that has some billion file inside , i tried copy some files for specific date but it's always did not respond for long time and did not give any result.. i tried everything with find command and also with xargs.. even this command find . -mtime -2 -print | xargs ls -d did not... (2 Replies)
Discussion started by: before4
2 Replies

6. Shell Programming and Scripting

copy specific files and count them - not as easy as it seems!

Hi all: Here's my dilemma: to identify files of a specific type, copy them to a new location while preserving the original file attributes (date, time, full path, etc), and at the same time capture the count of the number of files identified as a variable for later reporting. Here's where I... (9 Replies)
Discussion started by: Yamaha Evans
9 Replies

7. Shell Programming and Scripting

How to copy specific files when you don't know the file name?

I hope this isn't as silly as it sounds from the title of the thread. I have software that outputs files where the name starts with a real number followed by underscore as a prefix to an input file name. These will list in the directory with the file with the smallest real number prefix as the... (5 Replies)
Discussion started by: LMHmedchem
5 Replies

8. Shell Programming and Scripting

Delete all files if another files in the same directory has a matching occurence of a specific word

Hello, I have several files in a specific directory. A specific string in one file can occur in another files. If this string is in other files. Then all the files in which this string occured should be deleted and only 1 file should remain with the string. Example. file1 ShortName "Blue... (2 Replies)
Discussion started by: premier_de
2 Replies

9. Shell Programming and Scripting

Recursively copy only specific files from a directory tree

Hi I am a shell-script newbie and am looking to synchronize certain files in two directory structures. Both these directory-trees are in CVS and so I dont want the CVS directory to be copied over. I want only .sh and .pl files in each subdirectory under these directory trees to be... (3 Replies)
Discussion started by: sharpsharkrocks
3 Replies

10. Solaris

To copy the files newer than specific date

Dear all, Can you help me in copying files newer than speciifc date Thanks in advance, Rajesh (3 Replies)
Discussion started by: RAJESHKANNA
3 Replies
Login or Register to Ask a Question