Rename multiple files in shell
I like mmv for this kind of thing
mmv 'linux_*' '#1'
But you can also use rename
. Be aware that there are commonly two rename
commands with very different syntax. One is written in Perl, the other is distributed with util-linux, so I distinguish them as "perl rename" and "util rename" below.
With Perl rename:
rename 's/^linux_//' linux_*.mp4
As cweiske correctly pointed out.
With util rename:
rename linux_ '' linux_*.mp4
How can you tell which rename you have? Try running rename -V
; if your version is util rename it will print the version number and if it is perl rename it will harmlessly report and unknown option and show usage.
If you don't have either rename
or mmv
and don't want to or can't install them you can still accomplish this with plain old shell code:
for file in linux_*.mp4 ; do mv "$file" "${file#linux_}" ; done
This syntax will work with any POSIX sh conforming to XPG4 or later, which is essentially all shells these days.
Rename multiple files in Bash with random strings
quickest hack to get a random-letters string I can think of is
head -c24 /dev/urandom | base64 | tr -dc a-zA-Z
so
randomname() { head -c24 /dev/urandom | base64 | tr -dc a-zA-Z; }
for f in file*.txt; do mv "$f" `randomname`.txt; done
and your odds of a collision are down in the one-in-a-billion range even with a huge list. Add a serial number on the end of randomname
's output and that goes away too.
How to rename multiple files in several folders?
There are a thousand ways to do it, I'd do it with Perl, something like this will work:
find files -type f -name "file*" | perl -ne 'chomp; $f=$_; $f=~s/\/file/\/doc/; `mv $_ $f`;'
-ne
process as inline script for each line inputchomp
clean a newline$f
is new filename, same as old filenames/\/file/\/doc/
replace "/file" with "/doc" in the new filenamemv $_ $f
rename the file by running an OS command with back ticks
How to rename multiple files?
shopt -s extglob
for f in *; do
echo "$f: ${f/_*(0)/}"
# mv "$f" "${f/_*(0)/}" # for the actual rename
done
output
F_001_4837_blabla1.doc: F1_4837_blabla1.doc
F_045_8987_blabla2.doc: F45_8987_blabla2.doc
F_168_9092_blabla3.doc: F168_9092_blabla3.doc
Parameter Expansion
Parameter expansion can be used to replace the content of a variable. In this case, we replace the pattern _*(0)
with nothing.
${parameter/pattern/string}
Pattern substitution. The pattern is expanded to produce a pat-
tern just as in pathname expansion. Parameter is expanded and
the longest match of pattern against its value is replaced with
string. If pattern begins with /, all matches of pattern are
replaced with string. Normally only the first match is
replaced. If pattern begins with #, it must match at the begin-
ning of the expanded value of parameter. If pattern begins with
%, it must match at the end of the expanded value of parameter.
If string is null, matches of pattern are deleted and the / fol-
lowing pattern may be omitted. If parameter is @ or *, the sub-
stitution operation is applied to each positional parameter in
turn, and the expansion is the resultant list. If parameter is
an array variable subscripted with @ or *, the substitution
operation is applied to each member of the array in turn, and
the expansion is the resultant list.
Extended pattern matching
Extended pattern matching allows us to use the pattern *(0)
to match zero or more 0
characters. It needs to be enabled using the extglob
setting.
If the extglob shell option is enabled using the shopt builtin, several
extended pattern matching operators are recognized. In the following
description, a pattern-list is a list of one or more patterns separated
by a |. Composite patterns may be formed using one or more of the fol-
lowing sub-patterns:
?(pattern-list)
Matches zero or one occurrence of the given patterns
*(pattern-list)
Matches zero or more occurrences of the given patterns
+(pattern-list)
Matches one or more occurrences of the given patterns
@(pattern-list)
Matches one of the given patterns
!(pattern-list)
Matches anything except one of the given patterns
Rename multiple files in bash
How about
rename 's/(.*).js/_$1/' *.js
Check the syntax for rename on your system.
The above command will rename A.js
to _A
& so on.
If you want to retain the extension, below should help:
rename 's/(.*)/_$1/' *.js
Renaming multiple files using shell script
Try something like this:
#! /bin/bash
declare -i i=0
for f in *.csv.gz; do
: $((i++))
mv "$f" "$(printf "FILE%03d_%s.csv.gz" $i "$(date +%Y%m%d)")"
done
You can pass the names of the files into the script. In that case you have to use dirname
to get the name of the directory of each file.
#! /bin/bash
declare -i i=0
for f in "$@"; do
: $((i++))
mv "$f" "$(dirname "$f")"/"$(printf "FILE%03d_%s.csv.gz" $i "$(date +%Y%m%d)")"
done
Example:
$ mkdir {1,2,3}
$ touch {1,2,3}/{a,b,c}.csv.gz
$ ./rename.sh {1,2,3}/*.csv.gz
$ ls {1,2,3}
1:
FILE001_20211012.csv.gz FILE002_20211012.csv.gz FILE003_20211012.csv.gz
2:
FILE004_20211012.csv.gz FILE005_20211012.csv.gz FILE006_20211012.csv.gz
3:
FILE007_20211012.csv.gz FILE008_20211012.csv.gz FILE009_20211012.csv.gz
Related Topics
Allocating a Data Page in Linux with Nx Bit Turned Off
Escaping the Exclamation Point in Grep
How to Offload the 1Hz Tick in Dyntick Mode
How to Properly Quote This Bash Pipeline for Watch
Significance of Address 0X8048080
Jupyter Lab - Suppress Console Output
"Command Not Found" Piping a Variable to Cut When Output Stored in a Variable
Bash Assign Output to Variable Inside Here Document
How to Prompt User for Sudo Password
G++ Always Fails with Undefined Reference to _Unwind_Getipinfo
Replace Line with Space and Backslash with a String Containing Spaces
What Is a Good Linux Exit Error Code Strategy
Replace Bash Variables in Template File
Grep for String and Open at the Corresponding Line
Print the Directory Where the 'Find' Linux Command Finds a Match
In Bash How to Split a Column in Several Column of Fixed Dimension
Terminal Closes When I Source My Script (Run with Dot at the Start)