You were right to consider rename first. The syntax is a little strange if you're not used to regexes but it's by far the quickest/shortest route once you know what you're doing:
rename 's/\d{4}/2503/' file*
That simply matches the first 4 numbers and swaps them for the ones you specified.
And a test harness (-vn means be verbose but don't do anything) using your filenames:
$ rename 's/\d{4}/2503/' file* -vn
file0901201437404.p renamed as file2503201437404.p
file0901201438761.p renamed as file2503201438761.p
file1003201410069.p renamed as file2503201410069.p
file2602201409853.p renamed as file2503201409853.p
file2602201410180.p renamed as file2503201410180.p
Answer from Oli on Stack ExchangeVideos
You were right to consider rename first. The syntax is a little strange if you're not used to regexes but it's by far the quickest/shortest route once you know what you're doing:
rename 's/\d{4}/2503/' file*
That simply matches the first 4 numbers and swaps them for the ones you specified.
And a test harness (-vn means be verbose but don't do anything) using your filenames:
$ rename 's/\d{4}/2503/' file* -vn
file0901201437404.p renamed as file2503201437404.p
file0901201438761.p renamed as file2503201438761.p
file1003201410069.p renamed as file2503201410069.p
file2602201409853.p renamed as file2503201409853.p
file2602201410180.p renamed as file2503201410180.p
This should do the trick:
for f in file*; do mv
{f/${f:4:8}/25032014}; done
It replaces the string beween the 4th and the 12th character with "25032014".
I use rename all the time. It is pretty simple, but hopefully you know basic regex:
rename "s/SEARCH/REPLACE/g" *
This will replace the string SEARCH with REPLACE in every file (that is, *). The /g means global, so if you had a SEARCH_SEARCH.jpg, it would be renamed REPLACE_REPLACE.jpg. If you didn't have /g, it would have only done substitution once, and thus now named REPLACE_SEARCH.jpg. If you want case-insensitive, add /i (that would be, /gi or /ig at the end).
With regular expressions, you can do lots more.
Note that this rename is the prename (aka Perl rename) command, which supports complete Perl regular expressions. There is another rename which uses patterns, and is not as powerful. prename used to be installed by default on Ubuntu (along with Perl), but now you may have to do:
sudo apt install rename
Here are a few examples:
Prefix
Add:
rename 's/^/MyPrefix_/' *
document.pdfrenamed toMyPrefix_document.pdf
Remove:
Also you can remove unwanted strings. Let's say you had 20 MP3 files named like CD RIP 01 Song.mp3 and you wanted to remove the "CD RIP" part, and you wanted to remove that from all of them with one command.
rename 's/^CD RIP //' *
CD RIP 01 Song.mp3to01 Song.mp3
Notice the extra space in '^CD RIP ', without the space all files would have a space as the first character of the file. Also note, this will work without the ^ character, but would match CD RIP in any part of the filename. The ^ guarantees it only removes the characters if they are the beginning of the file.
Suffix
Add:
rename 's/$/_MySuffix/' *
document.pdfrenamed todocument.pdf_MySuffix
Change:
rename 's/\.pdf$/.doc/' *
will change Something.pdf into Something.doc. (The reason for the backslash is, . is a wildcard character in regexp so .pdf matches qPDF whereas \.pdf only matches the exact string .pdf. Also very important to note, if you are not familiar with BASH, you must put backslashes in SINGLE quotes! You may not omit quotes or use double quotes, or bash will try to translate them. To bash \. and "\." equals .. (But double-quotes and backslashes are used, for example "\n" for a newline, but since "\." isn't a valid back escape sequence, it translates into .)
Actually, you can even enclose the parts of the string in quotes instead of the whole: 's/Search/Replace/g' is the same as s/'Search'/'Replace'/g and s/Search/Replace/g to BASH. You just have to be careful about special characters (and spaces).
I suggest using the -n option when you are not positive you have the correct regular expressions. It shows what would be renamed, then exits without doing it. For example:
rename -n s/'One'/'Two'/g *
This will list all changes it would have made, had you not put the -n flag there. If it looks good, press Up to go back, then erase the -n and press Enter (or replace it with -v to output all changes it makes).
Note: Ubuntu versions above 17.04 don't ship with rename by default, however it's still available in the repositories. Use sudo apt install rename to install it
Try pyrenamer.
It's not integrated with nautilus, but it gets the job done. Here is a review.
Thunar (part of XFCE) also has a renamer that you can run separately.

Renaming files using mmv:
$ mmv '???-*' '#4'
^^^ ^ ^
123 4 4
You could also match digits with range match:
$ mmv '[0-9][0-9][0-9]-*.txt' '#4.txt'
^ ^ ^ ^ ^
1 2 3 4 4
(recursively rename files):
$ mmv ';???-*' '#1#5'
^^^^ ^ ^ ^
1234 5 1 5
;Expands to any number of directories (same as**/).*Matches any char zero or more times.?Matches any single character.[]Matches a list or and a range of characters.#References to the nth wildcard char in the from pattern.
With Perl-based rename command:
$ rename -n 's/\d{3}-//' [0-9][0-9][0-9]-*.txt
rename(000-hello.txt, hello.txt)
rename(001-world.txt, world.txt)
rename(002-ubuntu.txt, ubuntu.txt)
rename(003-linux.txt, linux.txt)
If the number of files is large enough to make the command exceed the shell's ARG_MAX, then you could use either
printf '%s\0' [0-9][0-9][0-9]-*.txt | xargs -0 rename -n 's/\d{3}-//'
or
find . -maxdepth 1 -name '[0-9][0-9][0-9]-*.txt' -exec rename -n 's/\d{3}-//' {} +
Note that [0-9][0-9][0-9]-*.txt is processed by the shell and needs to be a shell glob expression rather than a regular expression.
Remove the -n once you are happy that it is doing the right thing.
If your file format is source.fna => target.fna you can use mmv to rename your files. By leaving out the from to arguments on the command-line, mmv will take source-target pair, one per line, on the standard input.
awk -F '=>' '{print
2}' files.txt | mmv
mmv can actually handle this format directly, but it's more of a coincidence.
mmv ignores lines on the standard input that look like its own error and "done" messages, as well as all lines beginning with white space, and will accept pattern pairs with or without the intervening "->" (or "-^", "=>", or "=^").
cat file.txt | mmv
I created the following function. you have to use in this way:
$ furqan_mv filenames.txt
the file filenames.txt must have the following format:
oldfile => newfile
the extension is always fna. Here is the function:
furqan_mv() {
ext=".fna"
while IFS= read -r line; do
oldfile=`echo $line | awk '{print $1}'`
newfile=`echo $line | awk '{print $3}'`
mv $oldfile.
newfile.$ext
done < $1
}
You can do this with the rename command line utility. To do what you want you need a simple regular expression:
rename "s/.+_/ds/g"files
.+ represents everything up to (in this context) the last underscore (_) character (so this works with multiple underscores, as mentioned in your first example). This requires that there be at least one character before the underscore; if you might have file names like _20131012.zip, use .* instead. So this three-character string (.+_ or .*_) will match everything up to and including the last underscore in the filename. s/old/new/ means substitute the new string (ds) for the old string. The g means global and might not be necessary in this case.
or, using the cross-platform renamer:
$ renamer --regex --find '.+_' --replace 'ds' *
Adapted from one of Oli's answers:
rename -n 's/.+/our
i++; sprintf("%014d_1.jpg", $i)/e' *
This takes every file in the current directory and renames it with a number with 14 digits (I hope I counted correctly) followed by _1.jpg. our $i introduces a global variable i, which is then increased by one and printed with sprintf. e commands rename to evaluate the right side of the replacement (= everything between the second and the third /) as an expression rather than literally. If you're happy with the results, remove -n to perform the renaming.
If you want to dive into perl expressions and their beauty, the perldoc is the way to go.
Would this works for you :
i=1
for file in *; do
mv "$file" "$(printf %014d
((i+1))
done
It will rename every file in the current directory like this :
00000000000001_1.jpg
.
.
00000000000009_1.jpg
.
.
00000000000010_1.jpg
.
.
You can do it by a terminal command in a directory where these files are located.
rename 's/^video_//' *.mp4
That means select all filenames started with video_ and replace video_ with nothing. I guess s is for "substitute".
^ shows the beginning of string. If you omit ^, the first occurrence of video_ will be removed no matter where it is located in the string. But in your case it does not really matter.
Note: Ubuntu versions above 17.04 don't ship with rename package, however you can still install it from default repositories via sudo apt install rename
Using
rename(prename) :rename -n 's/^video_//' video_*.mp4If you are satisfies with the changes that are going to be made, remove
-nto let the operation happens actually :rename 's/^video_//' video_*.mp4Using
bashparameter expansion :for file in video_*.mp4; do mv -i "$file" "${file#video_}"; done${file#video_}is the parameter expansion pattern to removevideo_from the start of the file names.
Or
for file in video_*.mp4; do mv -i "$file" "${file/video_/}"; doneThis one assumes
video_comes only once in file names${file/video_/}is abashparameter expansion pattern that will replacevideo_from file names with blank.
I've written a bash script for you
#!/bin/bash
for file in *
do
name=$(echo "$file" | tr '[:lower:]' '[:upper:]')
name=AD${name#*_AD}
name=${name::6}
extension=${file#*.}
mv ${file} ${name}.${extension}
done
With # I remove all the (smallest possible) part in front of the string that matchs *_AD.
In the next line I cut the Sting in max length to 6.
I write the extension by remogin the smales part that matches *..
Then we move the file to ${name}.${extension}.
Hope it works well.
With perl-based rename:
$ rename -n 's/.*(AD\d+).*?./$1.$2/' *.ba[im]
rename(5891_1_0_AD3884_ACTCTCGA_S10.bam, AD3884.bam)
rename(5891_1_0_AD3884_ACTCTCGA_S10.bam.bai, AD3884.bam.bai)
rename(5891_1_AD3875_GAGCTTGT_S1.bam, AD3875.bam)
rename(5891_1_AD3875_GAGCTTGT_S1.bam.bai, AD3875.bam.bai)
rename(5891_2_AD3876_ACACGGTT_S2_R1.bam, AD3876.bam)
rename(5891_2_AD3876_ACACGGTT_S2_R2.bam.bai, AD3876.bam.bai)
Remove the -n once you are happy that it is doing the right thing.
If you have all of these files in one folder and you're on Linux you can use:
rename 's/test-this/REPLACESTRING/g' *
The result will be:
REPLACESTRING.ext
REPLACESTRING.volume001+02.ext
REPLACESTRING.volume002+04.ext
...
rename can take a command as the first argument. The command here consists of four parts:
s: flag to substitute a string with another string,test-this: the string you want to replace,REPLACESTRING: the string you want to replace the search string with, andg: a flag indicating that all matches of the search string shall be replaced, i.e. if the filename istest-this-abc-test-this.extthe result will beREPLACESTRING-abc-REPLACESTRING.ext.
Refer to man sed for a detailed description of the flags.
Use rename as shown below:
rename test-this foo test-this*
This will replace test-this with foo in the file names.
If you don't have rename use a for loop as shown below:
for i in test-this*
do
mv "$i" "${i/test-this/foo}"
done
To replace # by somethingelse for filenames in the current directory (not recursive) you can use the (Perl-)rename utility:
rename 's/#/somethingelse/' *
Characters like - must be escaped with a \.
For your case, you would want to use
rename 's/#U00a9/safe/g' *
Note that if you only want to operate on a certain selection of files, e.g., only *.jpg, adjust the final input to match that selection:
rename 's/#U00a9/safe/g' *.jpg
To perform a test before actually changing filenames, use the -n flag:
demo/> ls
Lucky-#U00a9NBC-125x125.jpg
Lucky-#U00a9NBC-150x150.jpg
demo/> rename -n 's/#U00a9/safe/g' *.jpg
rename(Lucky-#U00a9NBC-125x125.jpg, Lucky-safeNBC-125x125.jpg)
rename(Lucky-#U00a9NBC-150x150.jpg, Lucky-safeNBC-150x150.jpg)
For OS X, rename can be installed using homebrew: brew install rename.
This is not hard, simply make sure to escape the octothorpe (#) in the name by prepending a reverse-slash (\).
find . -type f -name 'Lucky-*' | while read FILE ; do
newfile="$(echo ${FILE} |sed -e 's/\\#U00a9/safe/')" ;
mv "${FILE}" "${newfile}" ;
done
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 's/linux_//' linux_*.mp4