'Shell Patterns: re-use matched string (part of the filename)

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.



Solution 1:[1]

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1