Linux Hack: How to rename a bunch of files
Renaming a bunch of files would be easy if the number of files is say less than 10. What if the number of files is 10+ or maybe in 100s? There is a simple trick in the command line to rename files using built-in Linux command line tools.
Note: File names should adhere to some pattern for this to work.
Navigate to the folder which contains the files to be renamed. To demonstrate I have created 14 files with names in a specific format.
$ ls -l
-rw-r--r-- 1 u1 group 0 Dec 20 20:17 log_2019_03_01.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:17 log_2019_03_02.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:17 log_2019_03_03.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:17 log_2019_03_04.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:17 log_2019_03_05.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:17 log_2019_03_06.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:17 log_2019_03_07.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:17 log_2019_04_01.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:18 log_2019_04_02.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:18 log_2019_04_03.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:18 log_2019_04_04.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:18 log_2019_04_05.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:18 log_2019_04_06.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:18 log_2019_04_07.log
Let us rename these files from log_<date>.log
format to <date>_recvlog.log
format
First, get the list of files to a temporary file.
$ ls log* > curr_file_names
$ cat curr_file_names
log_2019_03_01.log
log_2019_03_02.log
log_2019_03_03.log
log_2019_03_04.log
log_2019_03_05.log
log_2019_03_06.log
log_2019_03_07.log
log_2019_04_01.log
log_2019_04_02.log
log_2019_04_03.log
log_2019_04_04.log
log_2019_04_05.log
log_2019_04_06.log
log_2019_04_07.log
Create a new temporary file with the new file names.
$ cat curr_file_names | sed "s/^log_//g" | sed "s/\./_recvlog./g" > new_file_names
$ cat new_file_names
2019_03_01_recvlog.log
2019_03_02_recvlog.log
2019_03_03_recvlog.log
2019_03_04_recvlog.log
2019_03_05_recvlog.log
2019_03_06_recvlog.log
2019_03_07_recvlog.log
2019_04_01_recvlog.log
2019_04_02_recvlog.log
2019_04_03_recvlog.log
2019_04_04_recvlog.log
2019_04_05_recvlog.log
2019_04_06_recvlog.log
2019_04_07_recvlog.log
cat curr_file_names
— Dumps the file contents to stdout (standard output)
| (pipe)
— Used to connect the stdout of one command to the stdin of another command. In this case the first pipe connects the stdout of the cat command to the stdin of the sed command and the second pipe connects the stdout of the sed command to the stdin of another sed command.
sed "s/^log_//g"
— Stream editor tool is used to modify a string stream. In this specific case the command is substituting (s) the string ‘log_’ which occurs at the start of line (^) to an empty string. i.e. It removes log_ from all lines
sed "s/\./_recvlog./g"
— In this case, the character dot (.) is replaced with (_recvlog.) string.
> new_file_names
— Redirects the stdout of the previous command to the new_file_names file.
Create corresponding mv (move) commands for each file
$ paste curr_file_names new_file_names | sed "s/^/mv /g" > move_cmd
$ cat move_cmd
mv log_2019_03_01.log 2019_03_01_recvlog.log
mv log_2019_03_02.log 2019_03_02_recvlog.log
mv log_2019_03_03.log 2019_03_03_recvlog.log
mv log_2019_03_04.log 2019_03_04_recvlog.log
mv log_2019_03_05.log 2019_03_05_recvlog.log
mv log_2019_03_06.log 2019_03_06_recvlog.log
mv log_2019_03_07.log 2019_03_07_recvlog.log
mv log_2019_04_01.log 2019_04_01_recvlog.log
mv log_2019_04_02.log 2019_04_02_recvlog.log
mv log_2019_04_03.log 2019_04_03_recvlog.log
mv log_2019_04_04.log 2019_04_04_recvlog.log
mv log_2019_04_05.log 2019_04_05_recvlog.log
mv log_2019_04_06.log 2019_04_06_recvlog.log
mv log_2019_04_07.log 2019_04_07_recvlog.log
paste curr_file_names new_file_names
— Pastes contents of multiple files to stdout in columnar fashion.
sed "s/^/mv /g"
— sed in this case substitutes the beginning of the line with mv with a space.
> move_cmd
— Stores the output to move_cmd
Do the renaming of files
$ sh -x move_cmd
+ mv log_2019_03_01.log 2019_03_01_recvlog.log
+ mv log_2019_03_02.log 2019_03_02_recvlog.log
+ mv log_2019_03_03.log 2019_03_03_recvlog.log
+ mv log_2019_03_04.log 2019_03_04_recvlog.log
+ mv log_2019_03_05.log 2019_03_05_recvlog.log
+ mv log_2019_03_06.log 2019_03_06_recvlog.log
+ mv log_2019_03_07.log 2019_03_07_recvlog.log
+ mv log_2019_04_01.log 2019_04_01_recvlog.log
+ mv log_2019_04_02.log 2019_04_02_recvlog.log
+ mv log_2019_04_03.log 2019_04_03_recvlog.log
+ mv log_2019_04_04.log 2019_04_04_recvlog.log
+ mv log_2019_04_05.log 2019_04_05_recvlog.log
+ mv log_2019_04_06.log 2019_04_06_recvlog.log
+ mv log_2019_04_07.log 2019_04_07_recvlog.log
$ ls -l *.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:17 2019_03_01_recvlog.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:17 2019_03_02_recvlog.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:17 2019_03_03_recvlog.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:17 2019_03_04_recvlog.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:17 2019_03_05_recvlog.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:17 2019_03_06_recvlog.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:17 2019_03_07_recvlog.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:17 2019_04_01_recvlog.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:18 2019_04_02_recvlog.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:18 2019_04_03_recvlog.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:18 2019_04_04_recvlog.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:18 2019_04_05_recvlog.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:18 2019_04_06_recvlog.log
-rw-r--r-- 1 u1 group 0 Dec 20 20:18 2019_04_07_recvlog.log
sh -x move_cmd
— This commands run each line in move_cmd file in the shell (sh). The -x option is used to display the trace of running commands.
All commands list
$ ls log* > curr_file_names
$ cat curr_file_names | sed "s/^log_//g" | sed "s/\./_recvlog./g" > new_file_names
$ paste curr_file_names new_file_names | sed "s/^/mv /g" > move_cmd
$ sh -x move_cmd
References
https://www.gnu.org/software/sed/manual/sed.html
https://www.gnu.org/software/coreutils/manual/html_node/paste-invocation.html