3

Have lot of directories like the following

./parent/inventory_control-8118c470fa3811ed9add1fef7e5ef70f/snapshots/automation
./parent/configuration_data-6be54fa0fa3e11ed9add1fef7e5ef70f/snapshots/automation
./parent/zip_code-940ac1d0fa3f11ed9add1fef7e5ef70f/snapshots/automation

I would like to rename the directories by removing hypen and uuid from the directory name. The desired output is

./parent/inventory_control/snapshots/automation
./parent/configuration_data/snapshots/automation
./parent/zip_code/snapshots/automation

Can you please suggest a one line command to find all the directories and rename them? or a bash script as well can help.

  • 2
    Can you show us what you've tried, and where you're getting stuck? – Jim L. Dec 14 '23 at 23:09
  • Is the part to be removed always a dash followed by a 32 hex character sequence at the end of a directory name? – Chris Davies Dec 14 '23 at 23:23
  • 1
    Why must it be a one line command? Do you really value brevity over readability? – Chris Davies Dec 14 '23 at 23:25
  • 1
    Advice to newcomers: If an answer solves your problem, please accept it by clicking the large check mark (✓) next to it and optionally also up-vote it (up-voting requires at least 15 reputation points). If you found other answers helpful, please up-vote them. Accepting and up-voting helps future readers. See the relevant help-center article – Gilles Quénot Dec 15 '23 at 02:12

3 Answers3

2

Using Perl's rename (usable in any OS):

rename -n 's/-*//' ./parent/*/

or

rename -n 's@-[[:xdigit:]]+/snapshots/@/snapshots/@' ./parent/*/snapshots/

Remove -n switch, aka dry-run when your attempts are satisfactory to rename for real.

You can add 32 hex condition if that's makes sense:

rename -n 's@-[[:xdigit:]]{32}/snapshots/@/snapshots/@'
terdon
  • 242,166
2
 for f in ./parent/*; do mv "$f" "${f%%-*}"; done

(bash)

anick
  • 505
  • 2
  • 13
2

With the zsh shell:

autoload -Uz zmv
zmv -n '(**/)(?*)-[[:xdigit:]](#c32)(#q/)' '$1$2'

(remove the -n (dry-run) if happy)

  • autoload marks the zmv function as autoloadable which means that upon first invocation, the code of that function will be loaded from some file in one of the $fpath directories. With -U, alias expansion is not done upon that loading, with -z, it's loaded in zsh emulation, that is with a default set of options. Both safeguards to avoid customizations affecting the behaviour of that function. If you're using that function often, you may want to add that line to your ~/.zshrc.
  • zmv 'pattern' 'expression' finds files matching the pattern and renames it based on the result of the expression
  • (**/): matches and level of directories and captures it in $1.
  • (?*): at least one character, captured in $2.
  • [[:xdigit:]](#c32) a count of 32 hexadecimal digits
  • (#q/) a qualifier that restricts the match to files of type directory.
  • $1$2 computes the replacement.

zmv processes the files depth-first so if there's a dir/a-FeedADeadBeef654321BadFadedDecaf/b-11112222333344445555666677778888 directory, dir/a-FeedADeadBeef654321BadFadedDecaf/b-11112222333344445555666677778888 is renamed to dir/a-FeedADeadBeef654321BadFadedDecaf/b first and then dir/a-FeedADeadBeef654321BadFadedDecaf to dir/a.

It also does all the substitutions first and checks for conflicts before starting to do the renaming, to avoid losing data.