Bulk rename files
I have a number of files:
10.3.100.179_01_20161018_230014_5335.jpg
10.3.100.179_01_20161018_231514_0814.jpg
10.3.100.179_01_20161018_233014_5706.jpg
10.3.100.179_01_20161018_234514_0896.jpg
10.3.100.179_01_20161018_230114_5395.jpg
10.3.100.179_01_20161018_231614_1145.jpg
10.3.100.179_01_20161018_233114_6047.jpg
10.3.100.179_01_20161018_234614_0547.jpg
10.3.100.179_01_20161018_230114_5492.jpg
10.3.100.179_01_20161018_231614_1264.jpg
10.3.100.179_01_20161018_233114_6146.jpg
10.3.100.179_01_20161018_234614_0658.jpg
10.3.100.179_01_20161018_230214_5630.jpg
10.3.100.179_01_20161018_231714_7135.jpg
I want to rename with this format:
10.4.100.135_01_20161013131108389_TIMING.jpg
10.4.100.135_01_20161013131111390_TIMING.jpg
10.4.100.135_01_20161013131114401_TIMING.jpg
10.4.100.135_01_20161013131117431_TIMING.jpg
10.4.100.135_01_20161013131120418_TIMING.jpg
10.4.100.135_01_20161013131123461_TIMING.jpg
10.4.100.135_01_20161013131126511_TIMING.jpg
It needs to remove the _
in timestamp and add the _TIMING
.
Solution 1:
Install renameutils
and use qmv
with your favorite text editor with:
sudo apt install renameutils
qmv
loads all names in your editor and when you save and close it applies your changes to the actual files. If the changes are inconsistent (e.g. two files get the same name) it will abort without touching anything. It also handles circular renames correctly.
I usually do:
$ qmv -f do
so that it shows just one column of names (do: destination-only). Here's how it looks:
If you combine it with the multiple cursors of SublimeText, Atom or Visual Studio Code, it makes a very nice and powerful tool for bulk renaming. For instance, for Atom, you would do EDITOR="atom -w" qmv -f do
.
Solution 2:
Use rename
...
rename -n 's/^([0-9]+\.[0-9]\.[0-9]+\.[0-9]+_[0-9]+_)([0-9]+)_([0-9]+)_([0-9]+)\.jpg/$1$2$3$4_TIMING\.jpg/' *
With -n
this will output what it's going to do without making any changes:
rename(10.3.100.179_01_20161018_230014_5335.jpg, 10.3.100.179_01_201610182300145335_TIMING.jpg)
rename(10.3.100.179_01_20161018_231514_0814.jpg, 10.3.100.179_01_201610182315140814_TIMING.jpg)
rename(10.3.100.179_01_20161018_233014_5706.jpg, 10.3.100.179_01_201610182330145706_TIMING.jpg)
rename(10.3.100.179_01_20161018_234514_0896.jpg, 10.3.100.179_01_201610182345140896_TIMING.jpg)
If it looks right, remove the -n
$ rename 's/^([0-9]+\.[0-9]\.[0-9]+\.[0-9]+_[0-9]+_)([0-9]+)_([0-9]+)_([0-9]+)\.jpg/$1$2$3$4_TIMING\.jpg/' *
$ ls
10.3.100.179_01_201610182300145335_TIMING.jpg 10.3.100.179_01_201610182330145706_TIMING.jpg
10.3.100.179_01_201610182315140814_TIMING.jpg 10.3.100.179_01_201610182345140896_TIMING.jpg
Explaining...
-
s/something/something_else/
search and replace -
^
the beginning of the name (anchoring) -
[0-9]
any number -
+
one or more of the preceeding character -
\.
literal.
(without\
this matches any character) -
()
to keep this part -
$1$2$3$3
back references to the things matched earlier and kept with()
Note: the *
at the end of the command is matching all visible files in the current directory. Use a more suitable glob if necessary.
Solution 3:
mmv
can do it as in the following:
mmv '*_*_*_*_*.jpg' '#1_#2_#3#4#5_TIMING.jpg'
10.3.100.179_01_20161018_230014_5335.jpg 10.3.100.179_01_201610182300145335_TIMING.jpg
#1, #2, #3, ... is referencing each one to the matching '*' here.
It is even shorter with:
mmv '*_*_*.jpg' '#1#2#3_TIMING.jpg'