Test first. Put
echoin front ofmv, read the output, and then removeecho. Usemv -iormv -nwhen unsure.
Bash parameter expansion (no extra tools)¶
| Pattern | Effect |
|---|---|
${f%.txt} |
remove the shortest match of .txt from the end |
${f#prefix} |
remove from the start |
${f/old/new} |
replace the first old |
${f//old/new} |
replace all old |
${f/#abc/def} |
replace abc only at the start |
${f/%abc/def} |
replace abc only at the end |
# Change extension .txt -> .json
for f in *.txt; do mv -- "$f" "${f%.txt}.json"; done
# Change .base -> .rhel6 (preview first)
for f in *.base; do echo mv -- "$f" "${f%.base}.rhel6"; done
for f in *.base; do mv -- "$f" "${f%.base}.rhel6"; done
# Remove "_dev" anywhere in the name
for f in *_dev*; do mv -- "$f" "${f//_dev/}"; done
# Replace only the start of a name
for f in Project-Write*.txt; do mv -- "$f" "${f/#Project-Write/Writing-Journal}"; done
# abc01.txt abc02.txt -> def01.txt def02.txt
for f in abc*.txt; do mv -- "$f" "${f/#abc/def}"; done
# Rename .yml -> .yaml everywhere below a directory
find . -name '*.yml' -exec sh -c 'for f; do mv -- "$f" "${f%.yml}.yaml"; done' _ {} +
# Strip the last 20 characters (like a timestamp suffix): cut with substring expansion
for f in *; do mv -i -- "$f" "../out/${f::${#f}-20}"; done
# Example: import2kair.11.41.5499.C.out_2013-06-12_12-06-37 -> import2kair.11.41.5499.C.out
Loops over * (not $(ls)) handle spaces in names correctly.
Using sed for the replacement¶
for f in *triggers*; do mv -- "$f" "$(echo "$f" | sed 's/triggers/trigger/g')"; done
# Change a year in the names
for f in *2012*; do mv -- "$f" "$(echo "$f" | sed 's/2012/2013/')"; done
rename: there are two different commands¶
- Perl
rename(Debian/Ubuntu:renameorprename; Fedora:prenamefromperl-File-Rename) takes a Perl expression:
rename -n 's/\(1982\) - //; s/ - \(480p\)//' *.mkv # -n = dry run
rename 's/ - \(480p\)//' *.mkv
Turning Show (1982) - S08E01 - (480p).mkv into Show - S08E01.mkv is a typical use.
- util-linux
rename(Fedora/RHELrename) uses a plain-text form:rename <from> <to> <files>:
rename ' - (480p)' '' *.mkv
rename -v .base .rhel6 *.base
Check which you have: rename --version (util-linux prints "util-linux"). Scripts that use the wrong dialect fail or, worse, misnamed files. See also find -execdir and mv.