Linux How to rename multiple files at once

eye-catch Other techs

I wanted to rename multiple pictures at once because the default name is datetime based e.g. 20230219_072614.jpg. I want to rename them with the index.

  • something_1.jpg
  • something_2.jpg
  • something_3.jpg
  • something_n.jpg

Let’s learn how to do it on Linux.

Sponsored links

Who wants only the result

Beware that the directory will also be renamed.

i=1; for item in $(ls -c | grep file-names); do mv -n $item "new-name_$i"; i=$((i+1)) ; done
Sponsored links

Understand how for-loop works

A different index needs to be used for each file. So let’s use for-loop here. Go to the target directory and execute the following command.

$ for i in $(ls); do echo $i; done
20230219_072614.jpg
20230219_072849.jpg
20230219_074105.jpg
20230219_074414.jpg
20230219_074620.jpg
20230219_075202.jpg
20230219_075445.jpg
20230219_075713.jpg
20230219_081159.jpg
20230219_081317.jpg
20230219_081539.jpg
20230219_081545.jpg
20230219_081605.jpg
20230219_081620.jpg
20230219_081757.jpg
20230219_081825.jpg

It shows only file names. Let’s update it since we need an index.

$ i=0; for item in $(ls); do echo $i $item; i=$((i+1)); done
0 20230219_072614.jpg
1 20230219_072849.jpg
2 20230219_074105.jpg
3 20230219_074414.jpg
4 20230219_074620.jpg
5 20230219_075202.jpg
6 20230219_075445.jpg
7 20230219_075713.jpg
8 20230219_081159.jpg
9 20230219_081317.jpg
10 20230219_081539.jpg
11 20230219_081545.jpg
12 20230219_081605.jpg
13 20230219_081620.jpg
14 20230219_081757.jpg
15 20230219_081825.jpg

i is index and item is file name. When it’s i=$i+1, it is handled as string.

$ i=0; for item in $(ls); do echo $i $item; i=$i+1; done
0 20230219_072614.jpg
0+1 20230219_072849.jpg
0+1+1 20230219_074105.jpg
0+1+1+1 20230219_074414.jpg
0+1+1+1+1 20230219_074620.jpg
0+1+1+1+1+1 20230219_075202.jpg
0+1+1+1+1+1+1 20230219_075445.jpg
0+1+1+1+1+1+1+1 20230219_075713.jpg
0+1+1+1+1+1+1+1+1 20230219_081159.jpg
0+1+1+1+1+1+1+1+1+1 20230219_081317.jpg
0+1+1+1+1+1+1+1+1+1+1 20230219_081539.jpg
0+1+1+1+1+1+1+1+1+1+1+1 20230219_081545.jpg
0+1+1+1+1+1+1+1+1+1+1+1+1 20230219_081605.jpg
0+1+1+1+1+1+1+1+1+1+1+1+1+1 20230219_081620.jpg
0+1+1+1+1+1+1+1+1+1+1+1+1+1+1 20230219_081757.jpg
0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1 20230219_081825.jpg

So if we want to apply the same command to all files in the directory, the following command can be the base command.

$ i=0; for item in $(ls); do <write the desired command here>; i=$((i+1)); done

Sorting

It’s better to control the order of the files. Let’s check how to sort the result of ls command.

$ ls --help | grep sort
Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.
  -c                         with -lt: sort by, and show, ctime (time of last
                               with -l: show ctime and sort by name;
                               otherwise: sort by ctime, newest first
  -f                         do not sort, enable -aU, disable -ls --color
                               can be augmented with a --sort option, but any
                               use of --sort=none (-U) disables grouping
  -r, --reverse              reverse order while sorting
  -S                         sort by file size, largest first
      --sort=WORD            sort by WORD instead of name: none (-U), size (-S),
                             with --sort=time, sort by WORD (newest first)
  -t                         sort by time, newest first; see --time
  -u                         with -lt: sort by, and show, access time;
                               with -l: show access time and sort by name;
                               otherwise: sort by access time, newest first
  -U                         do not sort; list entries in directory order
  -v                         natural sort of (version) numbers within text
  -X                         sort alphabetically by entry extension

Sort ls result by updated time

To sort the files by updated time in asc order, add -tr. It needs to be reversed, so r option is also needed.

$ ls -ltr
total 26508
-rwxr----- 1 yuto yuto 1792365 Feb 19 07:26 20230219_072614.jpg
-rwxr----- 1 yuto yuto 1969414 Feb 19 07:28 20230219_072849.jpg
-rwxr----- 1 yuto yuto 1833915 Feb 19 07:41 20230219_074105.jpg
-rwxr----- 1 yuto yuto 1958573 Feb 19 07:44 20230219_074414.jpg
-rwxr----- 1 yuto yuto 1708049 Feb 19 07:46 aa20230219_074620.jpg
-rwxr----- 1 yuto yuto 1470538 Feb 19 07:52 20230219_075202.jpg
-rwxr----- 1 yuto yuto 1283972 Feb 19 07:54 20230219_075445.jpg
-rwxr----- 1 yuto yuto 1881061 Feb 19 07:57 bb20230219_075713.jpg
-rwxr----- 1 yuto yuto 2104242 Feb 19 08:11 20230219_081159.jpg
-rwxr----- 1 yuto yuto 1781741 Feb 19 08:13 20230219_081317.jpg
-rwxr----- 1 yuto yuto 1563078 Feb 19 08:15 20230219_081539.jpg
-rwxr----- 1 yuto yuto 1419720 Feb 19 08:15 20230219_081545.jpg
-rwxr----- 1 yuto yuto 1449851 Feb 19 08:16 20230219_081605.jpg
-rwxr----- 1 yuto yuto 1342188 Feb 19 08:16 20230219_081620.jpg
-rwxr----- 1 yuto yuto 1682583 Feb 19 08:17 20230219_081757.jpg
-rwxr----- 1 yuto yuto 1874102 Feb 19 08:18 20230219_081825.jpg

All files are picture taken by my smartphone. Therefore, modify time is before created (Birth) time. The created time is when I copied the data to my PC.

$ stat 20230219_072614.jpg 
  File: 20230219_072614.jpg
  Size: 1792365       Blocks: 3504       IO Block: 4096   regular file
Device: 10302h/66306d    Inode: 15217878    Links: 1
Access: (0740/-rwxr-----)  Uid: ( 1000/    yuto)   Gid: ( 1000/    yuto)
Access: 2023-02-19 09:14:15.816976842 +0100
Modify: 2023-02-19 07:26:14.000000000 +0100
Change: 2023-02-19 09:14:15.704971697 +0100
 Birth: 2023-02-19 09:14:15.692971146 +0100

When it’s used in for-loop, remove -l option.

i=0; for item in $(ls -tr); do <write the desired command here>; i=$((i+1)); done

Sort ls result by created time

If it’s necessary to sort it by created time, add -c option.

$ ls -lc
total 26508
-rwxr----- 1 yuto yuto 1792365 Feb 19 09:14 20230219_072614.jpg
-rwxr----- 1 yuto yuto 1969414 Feb 19 09:14 20230219_072849.jpg
-rwxr----- 1 yuto yuto 1833915 Feb 19 09:14 20230219_074105.jpg
-rwxr----- 1 yuto yuto 1958573 Feb 19 09:14 20230219_074414.jpg
-rwxr----- 1 yuto yuto 1470538 Feb 19 09:14 20230219_075202.jpg
-rwxr----- 1 yuto yuto 1283972 Feb 19 09:14 20230219_075445.jpg
-rwxr----- 1 yuto yuto 2104242 Feb 19 09:14 20230219_081159.jpg
-rwxr----- 1 yuto yuto 1781741 Feb 19 09:14 20230219_081317.jpg
-rwxr----- 1 yuto yuto 1563078 Feb 19 09:14 20230219_081539.jpg
-rwxr----- 1 yuto yuto 1419720 Feb 19 09:14 20230219_081545.jpg
-rwxr----- 1 yuto yuto 1449851 Feb 19 09:14 20230219_081605.jpg
-rwxr----- 1 yuto yuto 1342188 Feb 19 09:14 20230219_081620.jpg
-rwxr----- 1 yuto yuto 1682583 Feb 19 09:14 20230219_081757.jpg
-rwxr----- 1 yuto yuto 1874102 Feb 19 09:14 20230219_081825.jpg
-rwxr----- 1 yuto yuto 1708049 Feb 19 09:46 aa20230219_074620.jpg
-rwxr----- 1 yuto yuto 1881061 Feb 19 09:46 bb20230219_075713.jpg

When it’s used in for-loop, remove -l option.

i=0; for item in $(ls -c); do <write the desired command here>; i=$((i+1)); done

Rename a file

mv command can be used to rename a file.

$ mv 20230219_081159.jpg renamed.jpg
$ ls -l
total 26508
-rwxr----- 1 yuto yuto 1792365 Feb 19 07:26 20230219_072614.jpg
-rwxr----- 1 yuto yuto 1969414 Feb 19 07:28 20230219_072849.jpg
-rwxr----- 1 yuto yuto 1833915 Feb 19 07:41 20230219_074105.jpg
-rwxr----- 1 yuto yuto 1958573 Feb 19 07:44 20230219_074414.jpg
-rwxr----- 1 yuto yuto 1470538 Feb 19 07:52 20230219_075202.jpg
-rwxr----- 1 yuto yuto 1283972 Feb 19 07:54 20230219_075445.jpg
-rwxr----- 1 yuto yuto 1781741 Feb 19 08:13 20230219_081317.jpg
-rwxr----- 1 yuto yuto 1563078 Feb 19 08:15 20230219_081539.jpg
-rwxr----- 1 yuto yuto 1419720 Feb 19 08:15 20230219_081545.jpg
-rwxr----- 1 yuto yuto 1449851 Feb 19 08:16 20230219_081605.jpg
-rwxr----- 1 yuto yuto 1342188 Feb 19 08:16 20230219_081620.jpg
-rwxr----- 1 yuto yuto 1682583 Feb 19 08:17 20230219_081757.jpg
-rwxr----- 1 yuto yuto 1874102 Feb 19 08:18 20230219_081825.jpg
-rwxr----- 1 yuto yuto 1708049 Feb 19 07:46 aa20230219_074620.jpg
-rwxr----- 1 yuto yuto 1881061 Feb 19 07:57 bb20230219_075713.jpg
-rwxr----- 1 yuto yuto 2104242 Feb 19 08:11 renamed.jpg

The renamed file is listed at the end here. If you don’t want to overwrite the existing file, add -n option.

Rename multiple files with index

Let’s apply all commands into one command. I want to start with index 1. So the initial value for i is set to 1.

$ i=1; for item in $(ls -c | grep file-name); do mv -n $item "new-name_$i"; i=$((i+1)) ; done
$ ls
new-name_1   new-name_12  new-name_15  new-name_3  new-name_6  new-name_9
new-name_10  new-name_13  new-name_16  new-name_4  new-name_7
new-name_11  new-name_14  new-name_2   new-name_5  new-name_8

Be careful that the directories are also renamed if it matches the grep condition.

Check the following post if you want to register the command.

Comments

Copied title and URL