Renaming files in linux with a regex
I used to write perl scripts to do this, until I discovered the rename command.
It accepts a perl regex to do the rename:
for this, I just typed two commands:
rename 's/(\w+)-(\w+)-(\d\d)-(\d{4})-NODATA.txt\$1.$4$3$2.log$//' *
rename 'y/A-Z/a-z/' *.log
For some distros though, rename
doesn't have this functionality (see its man page), and you may have to install perl-rename
or prename
.
mmv is a standard linux utility to move/rename multiple files. It is available from the repos for most distributions. For your example above, you could do:
mmv '*-Log-*-*-*-NODATA.txt' '#l1.#4#3#2.log'
For more information, read this debaday article or the man page.
Since i don't have a rename command, i am relying on this:
for myfile in /my/folder/*; do
target=$(echo $myfile|sed -e 's/foo/bar/g')
mv "$myfile" "$target"
done
rename
util is not very "standard". Each distro ships with a different rename
tool. For instance, here on Gentoo, rename
is from sys-apps/util-linux
package and does not support regex.
Hamish Downer suggested mmv
, it seems useful, specially for use inside scripts.
On the other hand, for the general case, you might want renameutils. It has qmv
and qcp
commands, which will open a text editor of your choice (my preference: Vim) and allow you to edit the destination filenames there. After saving and closing the editor, qmv
/qcp
will do all the renaming.
Both mmv
and qmv
are smart enough to rename files in correct order and also to detect circular renames, and will automatically make a temporary file if needed.
To be fair:
rename 's/(\w+)-(\w+)-(\d\d)-(\d{4})-NODATA.txt\$1.$4$3$2.log$//' *.txt
gives this output:
Use of uninitialized value $4 in regexp compilation at (eval 1) line 1.
Use of uninitialized value $3 in regexp compilation at (eval 1) line 1.
Use of uninitialized value $2 in regexp compilation at (eval 1) line 1.
But:
rename -n 's/(\w+)-\w+-(\d{2})-(\d{2})-(\d{4})-NODATA\.txt$/$1.$4$3$2\.log/' *.txt && rename 'y/A-Z/a-z/' System.20090101.log
gives the right output:
System-Log-01-01-2009-NODATA.txt renamed as System.20090101.log
System.20090101.log renamed as system.20090101.log
replacing {-n} switch with {-v}