1

I would like to use find and rsync to copy any directory that contains at least one "wav" file. The copying should copy the whole folder if a "wav" file is present. I have this so far:

find . -name "*.wav" | rsync -armR --include="*/" --include="*.wav" --exclude="*" /users/lukew/desktop/merged /users/lukew/desktop/123;

This is good because the output is distributed into the correct directory at the output level as a single "wav" file. I'd also like the other files in the source directory to be included at the same time to go alongside the "wav" file in the output directory.

3
  • Your command doesn't make sense as rsync is doing nothing with the list of files generated by find. What do you actually want to achieve (preferably with examples)? Sep 23, 2017 at 16:30
  • 3
    Please don't leave all these comments here. Comments are easy to miss and hard to read and they can be deleted without warning. All relevant details need to be in the body of your question, so please edit and add them. Explain i) what you want to do; ii) what is actually happening.
    – terdon
    Sep 23, 2017 at 17:08
  • @LukeW Move all relevant comments into the text of the question (and remove them as comments). I would also be happy if you could include a listing of some part of the directory hierarchy that you are copying from, including file names. My solution works for me and at least one other person, and I think there's something up with the way the source directory is organised.
    – Kusalananda
    Sep 23, 2017 at 17:31

1 Answer 1

1

You need to figure out what directories include .wav files:

find . -type d \
    -exec sh -c 'set -- "$1"/*.wav; [ -e "$1" ]' sh {} ';' \
    -print

This goes through all directories under . and tries the glob pattern *.wav in all of them. If the pattern is unexpanded, then we assume that there is no .wav file there (this will fail if there is a file with the literal name *.wav in a directory and no other .wav files in the same directory).

Then we may incorporate rsync into the above command to sync these directories:

find . -type d \
    -exec sh -c 'set -- "$1"/*.wav; [ -e "$1" ]' sh {} ';' \
    -exec rsync -a {} /path/to/destination/ ';'

This will create a subdirectory under /path/to/destination for each directory found to contain a .wav file.

Testing:

$ tree Source
Source
|-- A
|   |-- a.wav
|   |-- hs.doc
|   `-- hy.xls
|-- B
|   |-- hs.doc
|   `-- py.xls
`-- C
    |-- CA
    |   |-- d.wav
    |   |-- h.doc
    |   `-- h.xls
    `-- CB
        |-- h.doc
        `-- hd.xls

5 directories, 10 files

Running the command:

$ find Source -type d -exec sh -c 'set -- "$1"/*.wav; [ -e "$1" ]' sh {} ';' -exec rsync -a {} Dest/ ';'

Checking the result:

$ tree Dest
Dest
|-- A
|   |-- a.wav
|   |-- hs.doc
|   `-- hy.xls
`-- CA
    |-- d.wav
    |-- h.doc
    `-- h.xls

2 directories, 6 files

The Dest directory was already existing, but empty.

12
  • 1
    Comments are not for extended discussion; this conversation has been moved to chat.
    – terdon
    Sep 23, 2017 at 18:59
  • Should I paste into terminal: $ find Source -type d \ -exec sh -c 'set -- "$1"/*.mobi; [ -e "$1" ]' sh {} ';' \ -exec rsync -a {} users/lukew/desktop/123dest/ ';' Question : should steps be implemented before this? If I include the $ at the beginning of find it says -bash: $: command not found. I removed the $ and began it with find. Then it says sh: -c: line1:syntax error: unexpected end of file sh: -c: line 0: unexpected EOF while looking for matching `" '
    – Luke W
    Sep 24, 2017 at 3:51
  • @LukeW The $ is the primary prompt shown by the shell (you don't type this, it's just showing that the command is typed at an interactive shell prompt). You should press return directly after each backslash, or write the whole command on one lang line (I have done that in the updated answer).
    – Kusalananda
    Sep 24, 2017 at 6:04
  • Yes that seems to work except how do I maintain the original directory structure, recursive option is that?
    – Luke W
    Sep 24, 2017 at 6:12
  • @LukeW The -a option for rsync includes the -r option for recursive copy. Remember, it's only the directories that contain a particular file type that is copied (as per the question), parent directories are ignored.
    – Kusalananda
    Sep 24, 2017 at 6:21

Not the answer you're looking for? Browse other questions tagged .