Home > Software engineering >  How to rename a consistently-named subdirectory across multiple directories?
How to rename a consistently-named subdirectory across multiple directories?

Time:12-02

I'm wanting to rename

123/1/ -> 123/v1/
foo/1/ -> foo/v1/
bar/1/ -> bar/v1/
345/1/ -> 345/v1/

I've searched and found a few related solutions, but not quite sure what is best in this instance. e.g.,

find . -wholename "*/1" -exec echo '{}' \;

successfully prints out all the paths relative to ., but {} expands to ./foo/1/, so I can't move from {} to {}/v1 for instance. I also tried

find . -wholename "*/1" -exec mv '{}' $(echo '{}' | sed 's/1/v1/') \;

with the idea that I would be invoking mv ./foo/1 ./foo/v1, but apparently it tries to move .foo/1/ to a subdirectory of itself.

Anyhow, just looking for the simplest way to do this bulk renaming. To be clear, I'm trying to move the literal subdirectory 1 to v1, not also 2 to v2.

CodePudding user response:

Like this, using perl rename (which may be different than the rename already existing on your system, use rename --version to check):

rename -n 's|([^/] /)(1)|$1v$2|' */1/ 

remove -n (dry-run) when the outputs is ok for you.

(note that you can use globstar on bash or something similar on other shells to recurse into deeper sub-directories)

CodePudding user response:

Something like this, untested, is IMHO the simplest way to do it using bash builtins and mandatory POSIX utils as long as your paths don't contain newlines:

while IFS= read -r old; do
    new="${old##*/}v1"
    echo mv -- "$old" $new"
done < <(find . -type d -name 1)

Remove echo once you're happy with the output from initial testing.

CodePudding user response:

This was tagged with fish. A solution using fish shell:

for file in **/1/; mv $file (dirname $file)/v1; end

CodePudding user response:

Try

find . -depth -type d -name 1 -execdir mv 1 v1 \;
  • The -execdir option to find is not POSIX, but it is widely supported by find implementations.
  • See What are the security issues and race conditions in using find -exec? for useful information about the -execdir option.
  • The -depth option is necessary both to support paths like foo/1/1/1 and to avoid warning messages when find can't traverse the newly-renamed 1 directories.
  • Related