Home > Software design >  Shell Patterns: re-use matched string (part of the filename)
Shell Patterns: re-use matched string (part of the filename)

Time:05-20

I have a directory, filled with .mp4 files, and another directory subdir in it. I know I can move all these files into subdir by running following command:

mv ./*.mp4 ./subdir/

But what if I wish to change extension of these files instead of moving? I'd like syntax like that to exist:

mv ./(*).mp4 "./@1.webm"

Here, parentheses do capturing a matched string, and @1 will be replaced by that string.

Of course, I've just made up such syntax, and that command will not work.

So, here is a question: How do I re-use matched pattern? If there is no similar syntax, what solution of this task should I use? Before You suggest: I do know one, by using cycle for f in ./*.mp4 ; do mv "$f" "${f/.mp4/.webm}" ; done, but I'd like to see more compact solutions than that one.

I'm not quite sure, how pattern matching works in shell, so I doubt, is there any simpler solution than for cycle mentioned above.

CodePudding user response:

zsh lets you make the loop shorter.

# Compare to
# for f in ./*.mp4 ; do mv "$f" "${f/.mp4/.webm}" ; done
for f (./*.mp4) mv "$f" "$f:r.webm"

It also provides the zmv command (modeled after the Perl script in @glennjackman's answer).

autoload zmv
zmv './(*).mp4' './$1.webm'

CodePudding user response:

With the perl rename

rename -n 's{(. )\.mp4}{./subdir/$1.webm}' *.mp4

If it looks right, remove the -n flag.

This is not pre-installed by default:

  • MacOS: using Homebrew: brew install rename
  • Ubuntu: apt install rename
  • Related