简体   繁体   中英

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 for f in./*.mp4; do mv "$f" "${f/.mp4/.webm}"; done 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.

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

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'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM