Goal 1: To change a subfolder "thumbs" to "thumb" if only one level deep.
Example Input:
./foo1/thumbs
./foo2/thumbs
./foo2/thumbs
Solution:
find . -maxdepth 2 -type d | sed 'p;s/thumbs/thumb/' | xargs -n2 mv
Output:
./foo1/thumb
./foo2/thumb
./foo2/thumb
Explanation:
Use find
to give you all "thumbs" folders only one level deep. Pipe the output to sed
. The p
option prints the input line and the rest of the sed
command changes "thumbs" to "thumb". Finally, pipe to xargs
. The -n2
option tells xargs
to use two arguments from the pipe and pass them to the mv
command.
Issue:
This will not catch deeper subfolders. You can't simple not use depth here because find
prints the output from the top and since we are replacing things with sed
before we mv
, mv
will result in a error for deeper subfolders. For example, ./foo/thumbs/thumbs/ will not work because mv
will take care of ./foo/thumbs first and make it ./foo/thumb, but then the next output line will result in an error because ./foo/thumbs/thumbs/ no longer exist.
Goal 2: To change all subfolders "thumbs" to "thumb" regardless of how deep.
Example Input:
./foo1/thumbs
./foo2/thumbs
./foo2/thumbs/thumbs
./foo2/thumbs
Solution:
find . -type d | awk -F'/' '{print NF, $0}' | sort -k 1 -n -r | awk '{print $2}' | sed 'p;s/\(.*\)thumbs/\1thumb/' | xargs -n2 mv
Output:
./foo1/thumb
./foo2/thumb
./foo2/thumb/thumb
./foo2/thumb
Explanation:
Use find
to give you all "thumbs" subfolders. Pipe the output to awk
to print the number of '/'s in each path plus the original output. sort
the output numerically, in reverse (to put the deepest paths on top) by the number of '/'s. Pipe the sorted list to awk
to remove the counts from each line. Pipe the output to sed
. The p
option prints the input line and the rest of the sed
command finds the last occurrence of "thumbs" and changes only it to "thumb". Since we are working with sorted list in the order of deepest to shallowest level, this will provide mv
with the right commands. Finally, pipe to xargs
. The -n2
option tells xargs
to use two arguments from the pipe and pass them to the mv
command.