Recently, I dual booted my PC with Ubuntu and Windows and for the first couple of days on Ubuntu, I was doing a lot of downloads to set things up and also cause school is in full swing and that just means a lot of PDFs, word documents and power point presentations.
Now my downloads folder is a mess, so naturally, instead of spending 5 minutes organizing it, I spent 30 minutes writing a bash script to organize it for me.
So let's talk bash.
What is Bash?
It's an acronym for the Bourne-Again SHell.
By Definition, it's the command language for the GNU operating system. Whenever you open a terminal on Ubuntu, those commands like mv, cp and others are bash terminal commands.
Let's write some Bash
Create a file called organize.sh
As with most scripts, we first need to specify that the script we're about to write is bash. To do this, we use the shebang #!/bin/bash
This indicates that the contents of this file will be a bash script.
After this, we need to specify where we will move all my data during the organization. For context, I have images, audio, videos, PDFs, power points, other bash scripts, zip files and others. So for simplicity's sake, we will only do 6 folders; Images, Audio, Video, PDFs, Scripts & Compressed Files. We can create all these folders using the mkdir
command like so;
mkdir Image_Files Audio_Files Video_Files PDFs Scripts Compressed_Files
Now that we have this, all that is left is to move the files into these folders. Here's where we need to get kinda smart. For something like image files, we identify them using different file extensions like .png .jpg .gif .tif
and others. So we need our script to look for anything with that specific extension and move it to the folder labelled Image_Files. A command like that would look something like this;
mv *.png *.jpg *.jpeg *.tif *.tiff *.bpm *.gif *.eps *.raw Image_Files
The asterisk(*) will match any character that precedes the extension. It is part of a regular expression syntax, but that's beyond the scope of this article.
So similarly, we match the file extensions for the other file types. We end up with something like this;
#Image Files
mv *.png *.jpg *.jpeg *.tif *.tiff *.bpm *.gif *.eps *.raw Image_Files
# Audio Files
mv *.mp3 *.m4a *.flac *.aac *.ogg *.wav Audio_Files
# Video Files
mv *.mp4 *.mov *.avi *.mpg *.mpeg *.webm *.mpv *.mp2 *.wmv Video_Files
# PDFs
mv *.pdf PDFs
# Scripts
mv *.py *.rb *.sh Scripts
#Compressed Files
mv *.rar *.zip Compressed_Files
Under Scripts, I added Python(.py) and Ruby(.rb) files because they can also be used to do some system scripting. We can also add some echo commands to let us know where the script is at while it's running. This doesn't need to be anything fancy, we can just add a single line at the end like this;
echo "All done organizing your messy messy downloads Folder"
Once you save the file, you will need to do a one more thing. The file doesn't have execute privileges just yet, but that's not a hard thing to solve. On your Linux terminal, type;
chmod u+x organize.sh
where organize.sh is the name of the file.
Now you can move this file into your downloads folder and run ./organize.sh
Did it work? Maybe a bit too well. The organize.sh file sorted itself into the scripts folder. To solve that, I decided to add these 3 lines at the end of my script.
cd Scripts
mv organize.sh ..
cd ..
so the final file should look like this;
#!/bin/bash
#Create Folders
mkdir Image_Files Audio_Files Video_Files PDFs Scripts Compressed_Files
#Image Files
mv *.png *.jpg *.jpeg *.tif *.tiff *.bpm *.gif *.eps *.raw Image_Files
# Audio Files
mv *.mp3 *.m4a *.flac *.aac *.ogg *.wav Audio_Files
# Video Files
mv *.mp4 *.mov *.avi *.mpg *.mpeg *.webm *.mpv *.mp2 *.wmv Video_Files
# PDFs
mv *.pdf PDFs
# Scripts
mv *.py *.rb *.sh Scripts
#Compressed Files
mv *.rar *.zip Compressed_Files
cd Scripts
mv organize.sh ..
cd ..
echo "All done organizing your messy messy downloads Folder"
What this does, is that it moves into the Scripts folder, removes the organize.sh script and moves it to the Downloads folder and then changes the current directory back to the Downloads folder. Now whenever you organize your downloads folder, the organize.sh script will not sort itself into the scripts folder.
Technically, we're done with the organize script. But if you want to learn how to make it into a system alias, keep reading.
Aliases and Bashrc
Why don't I want the organize script in the scripts folder? Because I want to add an alias to the .bashrc file. This would allow me to run a single command at any time, in any directory and have it sort my Downloads folder. A bit over-engineered, but that's how you learn.
So what are Aliases?
An alias in general English is defined as a false name that someone is identified by. In programming, it is defined as A nickname for something, which behaves in all ways as though you’d used the original name instead of the nickname.
A common command in bash is the ls command. But people can mistype it as sl. To avoid the shell telling you that it doesn't understand what you're saying, you can have an alias such that whenever you type sl, it executes the ls command. Such an alias would be like;
alias sl=ls
Another use of aliases is to execute verbose command with as few words as possible. For instance, instead of typing npx create-react-app newApp
you could have an alias as cra newApp
. This would be defined by:
alias cra="npx create-react-app"
You get the point. So now our alias to organize would have to be;
alias organize="cd ~/Downloads && ./organize.sh"
But this alias is only good for the currently running terminal. If we close this terminal, we lose this alias. So we need some permanence. We can do this by putting it in our .bashrc file.
Bashrc???
The .bashrc is a configuration file that is run whenever the user logs in. It includes setting up or enabling: coloring, completion, shell history, command aliases.
To edit your .bashrc using vim, you can just use
vim ~/.bashrc
Then go to the final line and insert this command
alias organize="cd ~/Downloads && ./organize.sh"
Save the file and then don't forget to run source ~/.bashrc
so that you can have those changes enacted on the current terminal.
Now everything is set up and you can always organize your downloads folder by running the organize command.
You can find the github repo Here
Top comments (6)
This might be simpler as a function or a script held in your
bin
directory.If you include the following in your
bashrc
or equivalent, you can drop scripts into~/bin
and the system will check there first.Then your
organize.sh
can move to~/bin/organize
and start with acd ~/Downloads || exit
line to make it work in the correct download directory. I often drop the.sh
extension on common utility scripts myself, though it doesn't really matter as long as it has a shebang.Thank you. I did not know about this. Will add it to V2
organize.sh does not have to be inside ~/Downloads, place it elsewhere and hardcode the download folder in the script.
Also, to avoid any errors while creating the target folders you can first perform a check on existence first. You can work with arrays and global path variables.
Good thread though. The main issue with Downloads for me, at least, is the perpetual choice between rubbish and "to keep" files.
Good script. Welcome to add it to SparrowHub so you can use it everywhere.
Will get right on it.