1. Introduction
Often, we may have many files with the same extension scattered across different directories on our computer. Thus, it can be difficult to find and manage such files. Moreover, they may take up a lot of space on the hard drive. Moving files with the same extension to a separate directory can help us solve this issue.
In this tutorial, we’re going to learn different ways of moving files to directories based on their extension using Linux utilities like mv, rsync, and find.
2. File Extensions
Before we get started, it’s important to understand what a file extension is. A file extension is a set of characters that come after the last period of a filename.
For example, the extension of example.txt is txt. This file extension helps both the operating system (OS) and its users figure out the file type and which program to use for opening the file.
Let’s check for files with a given type in our directory:
$ ls ./*.txt
./text_file1.txt ./text_file2.txt
Moving files to a directory based on their extension can be trickier in Linux. However, a little bit of knowledge and the right tools can make the task easier.
3. Using mv
One of the most common ways to move files and directories is the mv command-line tool.
We can use the mv command to move files with the same extension to a specific directory using wildcard characters. For example, let’s move all files with the txt extension to a directory called text_files:
$ mv *.txt /home/users/text_files/
In the above example, *.txt is a wildcard pattern that matches all files in the current directory that have the txt extension. Then the mv command moves all of these files to the text_files directory located at /home/users/text_files/. The concept of matching multiple files based on wildcard characters is called globbing.
The mv command overwrites existing files in the destination directory if they have the same name as the files being moved. To avoid overwriting, we can use the -n option:
$ mv -n *.txt /home/users/text_files/
If desired, we can use the -v option for verbose output, which makes mv display the name of each file. Also, the progress tool enables us to monitor the move between directories.
To move multiple files based on several extensions in one command, we can use the curly bracket expansion feature of Bash. With this, we can specify several extensions all at once in a single command:
$ mv *.{txt,pdf,jpg} /home/users/all_files/
In this case, the command matches all files in the current directory that have an extension of txt, pdf, or jpg, and moves them to the target directory at /home/users/all_files/. The curly bracket syntax {txt,pdf,jpg} specifies a comma-separated list of extensions to match.
We can also provide the complete path of the original directory before the * symbol like /home/users/downloads/*.{txt,pdf,jpg}.
4. Using rsync
The rsync command is a powerful and highly configurable utility for synchronizing files and directories between two locations.
For example, we can use rsync to move all files with a .pdf extension to another directory:
$ rsync /home/users/documents/*.pdf /home/pdf_files/
The above command uses wildcard *.pdf to find and move all files with the pdf extension from the original directory /home/users/documents/ to a new one /home/pdf_files.
We can also use the –include option with wildcard characters or a specific name to find the files based on extension type:
$ rsync -avr --exclude=abdx --include='*.pdf' /home/users/documents/ /home/pdf_files/
In this example, we’re moving files between the same two paths, but excluding the file abdx from the move:
- -a preserves the file attributes and permissions
- -v increases the verbosity of the output
- -r searches the files recursively from subdirectories
- –exclude=abdx excludes the file abdx from the move
We can also exclude files larger than a specific size by using the –max-size option:
$ rsync -avr --max-size=500m --exclude=abcx --include='*.pdf' /home/users/documents/ /home/pdf_files/
This excludes files larger than 500MB from moving. In the same way, we can use the –min-size option to exclude files smaller than a specific size.
Finally, we can also track the total progress of the move operation using the –info=progress2 option:
$ rsync -avr --info=progress2 --exclude=abcx --include='*.pdf' /home/users/documents/ /home/pdf_files/
The example above shows the total progress of the move operation.
By default, rsync copies files from one directory to another, thus keeping the copy of the files in the original directory. We can pass the –remove-source-files option to delete the files after sending them to the destination directory.
5. Extending mv With find and grep
Another command line tool that we can use to move files based on their extension is the find command. The find command searches for files and directories based on various criteria, such as their name, type, or size.
For example, we can use find to move all files with the jpg extension to another directory:
$ find /home/users/documents/ -name '*.jpg' -exec mv {} /home/image_files/ \;
This command searches for all jpg files in the /home/users/documents/ directory and its subdirectories, and then moves them to the directory image_files located at /home/image_files/. Let’s break it down to understand it:
- -name ‘*.jpg’ only considers files that have a name ending in .jpg
- -exec mv {} /home/image_files/ \; tells find to execute the mv command on each file that’s found
We can also exclude files from the move based on their name using grep. However, we use xargs to perform the move afterwards:
$ find /home/users/documents/ -name '*.jpg' | grep -v 'abdx' | xargs -I{} mv {} /home/image_files/
In this case, the grep -v command filters out any files that include abdx in their name from the list of files. Next, xargs -I{} mv {} moves all files that are left after the grep command.
The xargs command reads standard input and converts it to arguments. We can also add filters based on the file size using options -size -10M and -size +10M to find files smaller than 10MB and files larger than 10MB, respectively.
6. Conclusion
In this article, we learned different ways to move files to directories based on the extension.
We discussed the usage of the mv, rsync, and find commands to move files in different scenarios. Further, we looked at options for including and excluding files based on the name and size of the files. Additionally, we’ve learned about the options of rsync to track the progress of the move. Finally, we used a pipeline of commands to gain fine control over the operation.