zigamilek zigamilek - 1 month ago 9
Bash Question

How to create a duplicate of subdirectories using find

I have two subdirectories in

/home/ziga/Mounted/
. Each of those has multiple non-empty subdirectories:

/home/ziga/Mounted/dir1/subdir1-1
/home/ziga/Mounted/dir1/subdir1-2
...

/home/ziga/Mounted/dir2/subdir2-1
/home/ziga/Mounted/dir2/subdir2-2
...


Is there any way to use
find
to create empty directories in, say
/home/ziga/CombinedMounts
that would have exact same names as those that are two levels deep inside
/home/ziga/Mounted/
? This is the end-result I'm looking for:

/home/ziga/CombinedMounts/subdir1-1
/home/ziga/CombinedMounts/subdir1-2
/home/ziga/CombinedMounts/subdir2-1
/home/ziga/CombinedMounts/subdir2-2
...


I can get the list of directories using this command:

find /home/ziga/Mounted/ -maxdepth 2 -mindepth 2 -type d ! -name "lost+found" ! -name ".Trash*" -exec basename {} \;


But I cannot for the life of me figure out how to use its output in
mkdir -p
so that I would get the desired subdirectories.

Somehow they always end up in
/home/ziga/CombinedMounts/home/ziga/Mounted/...


I'm losing my mind, please help. :)

NOTE: some of the directory names contain spaces!

Answer

Try this:

find /home/ziga/Mounted/ -maxdepth 2 -mindepth 2 \
  -type d ! -name "lost+found" ! -name ".Trash*" \
  -exec sh -c 'mkdir -p /home/ziga/CombinedMounts/"$(basename "$0")"' "{}" \;

I'll explain only the parts that you haven't mentioned in the question.

We invoked sh because we cannot reliably pass the {} placeholder to an expression like mkdir -p "/path/$(basename "{}")". The expression also looks unclear with the placeholder.

The -c option sets the value of parameter 0 from the value of the operand after the command string (refer to the man page for sh):

-c Read commands from the command_string operand. Set the value of special parameter 0 (see Section 2.5.2, Special Parameters) from the value of the command_name operand and the positional parameters ($1, $2, and so on) in sequence from the remaining argument operands. No commands shall be read from the standard input.

Comments