1

I have a folder that contains sub-directories A,B,C and D. I need to copy directories A and D to another directory called 'copy' while excluding B and C(i.e. B and C doesn't get copied over). I was thinking about doing the following (in command-line pseudocode):

ls (selective ls on the source directory) | scp -r {returned value from the ls} {target directory} 

Is there a Linux command-line way to accomplish the above?

3 Answers 3

3

I'd suggest using find for this.

Let's create some test subjects:

$ mkdir -p ./testing/test{1,2,3,4} $ touch ./testing/test{1,2,3,4}/test{a,b} 

Will result in:

$ ls -R ./testing ./testing: test1 test2 test3 test4 ./testing/test1: testa testb ./testing/test2: testa testb ./testing/test3: testa testb ./testing/test4: testa testb 

Now, run

$ mkdir ./testing/copy $ find ./testing/ -mindepth 1 -maxdepth 1 ! -name test1 ! -name test3 ! -name copy -execdir cp -R '{}' ./copy/ ';' 

Will result in:

$ ls -R ./testing/ ./testing/: copy test1 test2 test3 test4 ./testing/copy: test2 test4 ./testing/copy/test2: testa testb ./testing/copy/test4: testa testb ./testing/test1: testa testb ./testing/test2: testa testb ./testing/test3: testa testb ./testing/test4: testa testb 

Background information:

Summary: find the directories which need to be copied and execute the copy command. In this case, let's copy all directories but 'test1' and 'test3'.

The -mindepth 1 option will prevent find from including the . and possibly .. directories, since these are on depth 0.

The -maxdepth 1 option will prevent find from copying every single subdirectory individually. The command cp -R handles the subdirectories, so they are covered.

Use -execdir instead of -exec, so you don't have to include the whole path as the target directory for cp command.

DO NOT forget to mkdir your target directory before running find, and DO NOT forget to exclude this directory from the result! Hence the ! -name copy option in my example.

I hope this points you in the right direction.

Sign up to request clarification or add additional context in comments.

Comments

2

The simple answer is to only copy the directories you want:

scp -r A D anotherhost:/path/to/target/directory 

This will do exactly what you've described in your example. A more general solution might look something like this:

scp -r $(ls | egrep -v '^(B|C)$') anotherhost:/path/to/target/directory 

This command will work as long as the number of files in your source directory is not large. As the number of files goes up, you'll eventually run into a "command too long" error.

Instead of using scp, you could use rsync, which has a variety of mechanisms for including/excluding files. For example:

rsync --exclude='B/' --exclude='C/' . anotherhost:/path/to/target/directory 

Comments

0

If you really know your directories, simply add all to the scp:

scp A/* D/* targetHost:/copy 

The only problem with this solution is, that it "mixes" your files in the copy directory. Probably, it dosen't matter :-)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.