- Find multiple files and rename them in Linux
- 13 Answers 13
- How to Use the find Command With exec
- Using exec command with the output of find command
- Practical examples of combining find and exec commands
- 1. Find and display file attributes
- 2. Find and rename files
- 3. Collect and store file sizes
- 4. Remove files with specific parameters
- 5. Execute specific tools
- 6. Change the ownership of files and directories
- 7. Changing the permission of files
- 8. Collect md5sum for each file
- 9. Combine exec with grep Command
- Bonus tip: Find with multiple exec commands
- Conclusion
- How to Find and Rename Files in Linux
- 1. Renaming Files via mv Command
- 2. Rename Mulitple Files Using mv and find Commands
- 3. Rename Files Using Bash Script
Find multiple files and rename them in Linux
I am having files like a_dbg.txt, b_dbg.txt . in a Suse 10 system. I want to write a bash shell script which should rename these files by removing «_dbg» from them. Google suggested me to use rename command. So I executed the command rename _dbg.txt .txt *dbg* on the CURRENT_FOLDER My actual CURRENT_FOLDER contains the below files.
CURRENT_FOLDER/a_dbg.txt CURRENT_FOLDER/b_dbg.txt CURRENT_FOLDER/XX/c_dbg.txt CURRENT_FOLDER/YY/d_dbg.txt
CURRENT_FOLDER/a.txt CURRENT_FOLDER/b.txt CURRENT_FOLDER/XX/c_dbg.txt CURRENT_FOLDER/YY/d_dbg.txt
Its not doing recursively, how to make this command to rename files in all subdirectories. Like XX and YY I will be having so many subdirectories which name is unpredictable. And also my CURRENT_FOLDER will be having some other files also.
13 Answers 13
You can use find to find all matching files recursively:
find . -iname "*dbg*" -exec rename _dbg.txt .txt '<>' \;
EDIT: what the ‘<>‘ and \; are?
The -exec argument makes find execute rename for every matching file found. ‘<>‘ will be replaced with the path name of the file. The last token, \; is there only to mark the end of the exec expression.
All that is described nicely in the man page for find:
-exec utility [argument . ] ; True if the program named utility returns a zero value as its exit status. Optional arguments may be passed to the utility. The expression must be terminated by a semicolon (``;''). If you invoke find from a shell you may need to quote the semicolon if the shell would otherwise treat it as a control operator. If the string ``<>'' appears anywhere in the utility name or the argu- ments it is replaced by the pathname of the current file. Utility will be executed from the directory from which find was executed. Utility and arguments are not subject to the further expansion of shell patterns and constructs.
How to Use the find Command With exec
Find works on searching files based on a number of criteria. The exec command gives you the ability to work on those results. Here are some examples of find exec command combination.
You can take your findings to the next level by actually doing specific operations on the found files.
For example, you found all the files with .jpeg extension. How about renaming them with .jpg extension?
You cannot just pipe redirect the find command output to another command. It won’t work that simply.
You have two ways to execute other commands on the result of the find command:
There is already a detailed article on xargs command. This tutorial will focus on combining find and exec commands.
Using exec command with the output of find command
The basic syntax to execute find with exec is as follows:
find [path] [arguments] -exec [command] <> \;
Here’s a quick explanation:
- [command] is what you want to execute over results given by the find command.
- <> is a placeholder that is used to hold results given by the find command.
- \; says that for each found result, the [command] is executed. You need to escape the ; here and hence \;.
There is another syntax that is slightly different from the above and is as follows:
find [path] [arguments] -exec [command] <> +
Here, + says for every result of the find command, the [command] is executed only once. All the results are passed to the [command] as arguments together. + does not need to be escaped with \+ .
Still confused about the use of <> \; and <> + ?
<> \; is like this (executing the commands for each found result):
ls file1.txt ls file2.txt ls file3.txt
<> + is like this (executing the command once with all results argument):
ls file1.txt file2.txt file3.txt
While it may seem like using <> + is the better option here, it’s the opposite. If the find commands throw 50 results, you cannot pass them all as arguments together because there are restrictions on maximum command line length.
This is why you are better with <> \; unless you know exactly what you need.
Practical examples of combining find and exec commands
Let me share some common examples of find exec commands so that you can understand them better.
1. Find and display file attributes
In the first simple example of find exec command, I am going to display all the lock files that are under the /tmp directory and display their properties.
sudo find /tmp/ -type f -name *lock -exec ls -l <> \;
[email protected]:~$ sudo find /tmp/ -type f -name *lock -exec ls -l <> \; -r--r--r-- 1 gdm gdm 11 Jul 17 08:01 /tmp/.X1024-lock -r--r--r-- 1 gdm gdm 11 Jul 17 08:01 /tmp/.X1025-lock
2. Find and rename files
Yes, using find with exec you can rename files easily. The mv command is used for renaming the files. I’ll be doing the same.
sudo find /home/sagar/Downloads/ -type f -name 'ubuntu*' -exec mv <> <>_renamed \;
The above command finds the files that start with the name ubuntu and store them inside the placeholder. Once the process of storing results inside the placeholder, it will add «_renamed» at the end of each file stored inside the placeholder.
3. Collect and store file sizes
In this example, I will show you how you can collect the size of available files under a certain directory and create a file to save the given output.
I will collect each file’s size under the /tmp directory and save the output under the /root directory with the filename of du_data.out
sudo find /tmp/ -type f -exec du -sh <> \; > /root/du_data.out
Now, let’s have a look at what the recently created file under /root directory looks like.
4. Remove files with specific parameters
Please be extra careful while automatically removing files. It could be catastrophic if you don’t pay attention. Either use the interactive delete with rm -i or see the result of the find command first.
Another common example of the find exec command combination is to find files greater than a certain size and remove them. This works well if you are cleaning old logs.
I am removing files larger than 100 MB for demonstration under my Desktop directory.
find ~/Desktop -size +100M -exec rm <> \;
Similarly, you can also remove files based on how old they are. For example, let’s remove files that are older than 10 days.
sudo find /tmp/ -type f -mtime +10 -exec rm <> \;
Here I used -mtime which identifies data modified in the last 24 hours and when paired +10 with it, it found and deleted files that are older than 10 days.
5. Execute specific tools
There are various cases where you may want to start certain tools or packages after finding the files.
For example, when I’m searching for any mp3 file, I want to run id3v2 which will bring details about found mp3 file.
find . -name "*.mp3" -exec id3v2 -l <> \;
id3v2 is the package that will show the details about the mp3 file and -l is used to show each mp3 tag associated with found mp3.
6. Change the ownership of files and directories
Changing the ownership of files and directories is another example of how powerful the combination of find and exec is.
Here, I am looking for the files owned by the user named sagar and then change their ownership to milan .
sudo find /home/sagar/disk/Downloads -user sagar -type f -exec chown milan <> \;
7. Changing the permission of files
So how about changing permissions of files using find and exec?
sudo find /home/sagar/disk/Downloads -type f -exec chmod 644 <> \;
In the above command, I used -type f so the command will only be applied to files under the given directory.
8. Collect md5sum for each file
In this example, I will demonstrate how you can collect md5sum for each available file under the /tmp directory.
sudo find /tmp/ -type f -exec md5sum <> \;
As you can see, the applied command collected md5sum for each available file with their names and md5sum.
But what if you want to save this output and to certain directly with a different name? you just have to follow the given command and change names directly accordingly:
sudo find /tmp/ -type f -exec md5sum <> \; > /Documents/checksumdata.out
9. Combine exec with grep Command
The find command works on the file names. The grep command works on the contents of the files.
Combine the find and grep together with exec and you got yourself a powerful search tool in the Linux command line.
For example, the command below searches for all the files that have .hbs extension. With grep, it searches inside the content of those .hbs files for the string ‘excerpt’.
find . -type f -name "*.hbs" -exec grep -iH excerpt <> \;
With the -H option, grep command will show the file names for each match. Here’s the output:
[email protected]:~/Downloads/casper-hyvor$ find . -type f -name "*.hbs" -exec grep -iH excerpt <> \; ./author.hbs:>./partials/post-card.hbs: > ./partials/post-card.hbs:>./post.hbs: > ./post.hbs:>
./tag.hbs:
Bonus tip: Find with multiple exec commands
Yes, you can chain multiple exec commands with single find command.
Let me take the same example that you saw in the previous section and use two exec commands.
find . -type f -name "*.hbs" -exec echo <> \; -exec grep excerpt <> \;
It’ll search for the .hbs files first and then echo their name with first exec command. And then, those files will be searched for the «excerpt» string.
The output will be slightly different than the one in the previous command:
[email protected]:~/Downloads/casper-hyvor$ find . -type f -name "*.hbs" -exec echo <> \; -exec grep excerpt <> \; ./index.hbs ./page.hbs ./default.hbs ./author.hbs>./error-404.hbs ./error.hbs ./partials/icons/twitter.hbs ./partials/icons/fire.hbs ./partials/icons/lock.hbs ./partials/icons/loader.hbs ./partials/icons/rss.hbs ./partials/icons/avatar.hbs ./partials/icons/facebook.hbs ./partials/post-card.hbs >>./post.hbs >>
./tag.hbs
Conclusion
Find is an already powerful command for searching files based on a number of criteria. The exec command gives you the ability to work on the result of the find command.
The examples I shared here are just a glimpse. Together, the find-exec command combination gives you endless possibilities for doing things in the Linux command line.
How to Find and Rename Files in Linux
Linux offers multiple terminal command solutions for renaming files regardless of the different paths or locations associated with the targeted files. Renaming a single file is easy but what happens when you have multiple files that should be instantaneously renamed?
This article guide provides an answer to this question.
1. Renaming Files via mv Command
The mv command is inbuilt into all major Linux distributions. The standard approach of renaming a single file via the mv command is represented with the following syntax:
$ mv [OPTIONS] [current/file/name] [new/file/name]
Consider the following files within the directory path $HOME/Downloads/backup:
To rename file1.txt to file10.txt we would implement the command:
As expected, the file was successfully renamed. What if there were multiple file1.txt files on different directory paths and we wish to rename them instantaneously?
2. Rename Mulitple Files Using mv and find Commands
The find command searches for files from a specified directory path as its starting point, which is an inbuilt command and comes pre-installed on all major Linux distributions.
In our case, if we were to rename the above existing text files to have html files’ extension, the appropriate syntax to use would be:
$ find . -depth -name "[current/filename/element]" -exec sh -c 'f="<>"; mv -- "$f" "$[new/filename/element]"' \;
Implementing the above syntax gives us:
$ find . -depth -name "*.txt" -exec sh -c 'f="<>"; mv -- "$f" "$.html"' \;
Explanation of the options used in the above find command.
- find . starts the search from the current directory path.
- -depth processes all the parent directory content.
- -name points to the current filename extension that needs changing.
- -exec initiates the execution of the mv command based on matched files.
3. Rename Files Using Bash Script
To rename files using the bash script, first, you need to create a script file.
Add the following content:
#!/bin/bash for f in $HOME/Downloads/backup/*.html; do mv -- "$f" "$.pdf" done
Here, we are using For Loop expression to search for all HTML files inside the directory $HOME/Downloads/backup and then executing an mv command to rename the HTML files extension to PDF file extension.
Make the script executable and run it.
$ chmod +x file_renamer.sh $ sh file_renamer.sh
The command execution was a success.
Combining the mv command with the find command or using it inside a bash script provides effective solutions to renaming multiple files at once under a Linux operating system environment.
Do you know any other way of renaming files in Linux? do share your views on the same in the comments section below.