Batch rename files
Solution 1
This should make it:
rename 's/^[0-9]*-//;' *
It gets from the beginning the block [0-9]
(that is, numbers) many times, then the hyphen -
and deletes it from the file name.
If rename
is not in your machine, you can use a loop and mv
:
mv "$f" "${f#[0-9]*-}"
Test
$ ls
23-aa hello aaa23-aa
$ rename 's/^[0-9]*-//;' *
$ ls
aa hello aaa23-aa
Or:
$ ls
23-a aa23-a hello
$ for f in *;
> do
> mv "$f" "${f#[0-9]*-}"
> done
$ ls
a aa23-a hello
Solution 2
I think this command would better if you execute the command below:
ls * | sed -e 'p;s/old-name/new-name/' | xargs -n2 mv
Here
ls * - lists files in curent folder
sed -e - executes expression
p; - prints old file name
s/old-name/new-name/ - produce new filename
xargs -n2 - handles two arguments to mv
mv - gets two parameters and do move operation
Recommendation: before executing mv verify what you do is what you want to achieve with echo.
ls * | sed -e 'p;s/old-name/new-name/' | xargs -n2 echo
Following example renames
SCCF099_FG.gz5329223404623884757.tmp to
SCCF099_FG.gz
ls *tmp | sed -e 'p;s/\([0-9]\)\+\.tmp/ /g' | xargs -n2 echo
ls *tmp | sed -e 'p;s/\([0-9]\)\+\.tmp/ /g' | xargs -n2 mv
Solution 3
If the first numbers are always the same length:
for F in *new ; do
mv $F ${F:8}
done
The ${parameter:number}
does a substring expansion - takes the string starting at the 8th character.
There are many other string edits available in expansions to handle other cases.
Solution 4
Using renamer (Windows, Mac and Linux friendly):
$ renamer --find '/\d+-(.*)/' --replace '$1' *
This will strip all numbers and first hyphen from the start of all files in the current directory.
Solution 5
This might look a little complex, but it's pretty effective and works well on both *nix and OSX systems. It also acts recursively, renaming files in the current directory as well as any subdirectories:
find . -regex '.*/[0-9]\{7\}[-].*' -print > temp1 && \
cp temp1 temp2 && \
vi -c ":g/\([0-9]\{7\}[-]\)\(.*\)/s//\2/" -c ":x" temp2 && \
paste temp1 temp2 > temp3 && \
vi -c ":g/^/s//mv /" -c ":x" temp3 && \
sh ./temp3 && \
rm temp1 temp2 temp3
Here's a breakdown of what just happened:
The first line says to find (find
) all files, starting with those in the current directory (.
), whose name matches the pattern (-regex
) of "7 numbers, followed by a dash, followed by 0 or more characters" ('.*/[0-9]\{7\}[-].*'
), and write those file names and their respective paths (-print
) to a file called temp1 (> temp1
). Note that the -print
directive is probably not necessary in most cases but it shouldn't hurt anything.
find . -regex '.*/[0-9]\{7\}[-].*' -print > temp1 && \
Then, copy (cp
) the contents of temp1 to a file called temp2.
cp temp1 temp2 && \
Next, open the file temp2 using the vi text editor and give vi two commands (using -c
to signify each new command):
- Command #1:
- Search each line of temp2 (
:g
) for the same pattern we searched for above, except this time group the results using parentheses (\([0-9]\{7\}[-]\)\(.*\)
). - For each matching line, move the cursor to where the match was found and replace the whole match with only the second group of the matched pattern (
\2
).
- Search each line of temp2 (
- Command #2:
- Save the changes made to temp2 and close the file (
:x
).
- Save the changes made to temp2 and close the file (
The result of which being this:
vi -c ":g/\([0-9]\{7\}[-]\)\(.*\)/s//\2/" -c ":x" temp2 && \
Now, concatenate the lines from temp1 with those of temp2 (paste
) and write each newly combined line to a file called temp3 (> temp3
).
paste temp1 temp2 > temp3 && \
Next, run vi again, doing the same steps as above except this time search for the beginning of each line (^
) inside the file temp3 and add mv and one space right after it (mv
).
vi -c ":g/^/s//mv /" -c ":x" temp3 && \
Then, execute the contents of temp3 (./temp3
) as a shell script (sh
).
sh ./temp3 && \
Finally, remove (rm
) each of the temporary files we created during the whole process.
rm temp1 temp2 temp3
van
Updated on July 17, 2022Comments
-
van almost 2 years
I want to batch re-name a number of files in a directory so that the preceding number and hypen are stripped from the file name.
Old file name: 2904495-XXX_01_xxxx_20130730235001_00000000.NEW New file name: XXX_01_xxxx_20130730235001_00000000.NEW
How can I do this with a linux command?
-
flx over 10 yearspossible duplicate of Renaming files in bash
-
-
Yossarian over 10 yearsThis doesn't work with my version of
rename
(util-linux-ng 2.17.2). What version are you using? -
David Souther over 10 yearsrename is in util-linux on Fedora and Debian releases, but doesn't seem to be included by default on OSX.
-
fedorqui over 10 years@Yossarian check my updated answer, using
mv
. Does it work to you? -
Yossarian over 10 yearsYep, the
mv
command works for me. It seems there must be two versions ofrename
- mine requires three arguments (rename from to file
). -
mindsupport almost 10 yearsIs it possible to install with dependencies ?
-
Lloyd almost 10 yearsi'm not sure what you mean.. there are install instructions on the renamer site.. does that help?
-
mindsupport almost 10 yearsnode package manager seems having issues with package dependencies, so it didn't install just one command, and npm didn't install dependencies in auto mode.
-
Lloyd almost 10 yearsi just ran
npm install -g renamer
- it installed correctly and works fine.. please ensure you have the latest node.js installed.. if you're still having problems, raise an issue here -
Ryan about 8 yearsSuper helpful. Thanks!
-
Luke Davis about 8 yearsI see this is old; but can you break down what's going on in this line? Here's my understanding: in the call to
sed
, if say there are 5 files present, the expression string prints each line and then prints its find-and-replaced copy immediately below; then,xargs
parses this list of 10 items now 2-at-a-time, and passes them as arguments tomv
. Is that right? -
fedorqui almost 8 years@cjungel not sure what you mean
-
Peter Nowee over 6 yearsSlight variation I used for filenames containing spaces:
find . -print0 | sed -z -e 'p;s/old-name/new-name/' | xargs -n2 -0 mv
.