I try to be organised, and put everything in folders where they belong, but, especially at work, this all stops being important after a couple of years, and becomes more difficult to find things especially when backed up. This one liner can resolve all of that by moving each file type to a directory of its own, retaining any duplicate files for further inspection. It may be best to keep a backup of all the original file locations where files of many types come together to make a whole.
Here is my one liner, which needs to be placed in the top directory. One can add as many different file extensions as needed into the variable array EXTS. I have used txt and jpg as example extensions.
1 2 3 |
shopt -s globstar dotglob; myexts=(txt jpg); for ext in "${myexts[@]}"; do mkdir $ext; \ mv --backup=numbered **/*.${ext} $ext; rename 's/~$//' "./$ext/"*; done |
If I break it down a bit with comments:
# allows sub directory matching, and moving of hidden files and files in hidden directories
1 |
shopt -s globstar dotglob; |
#sets the variable with extensions, from 1 to many
1 |
<span style="color: #ff6600;"><strong>myexts=(txt jpg);</strong></span> |
#runs the code for each extension in the variable array EXTS
1 |
<span style="color: #ff6600;"><strong>for ext in "${myexts[@]}";</strong></span> |
#do something
1 |
<span style="color: #ff6600;"><strong>do</strong></span> |
#make a directory with the same name as the extension
1 |
<span style="color: #ff6600;"><strong>mkdir $ext;</strong></span> |
#move files with the extension in all sub directories to the created top
#level directory of the same name.
# The **/* code which is enabled by the shopt -s globstar command
# allows matching with all sub directories
# The –backup=numbering ensures no files are overwritten and duplicates
# are copied over and renamed
1 |
<span style="color: #ff6600;"><strong>mv --backup=numbered **/*.${ext} $ext;</strong></span> |
# renames the duplicate files by removing the last character if it
# is a “~” in order to unhide the files. There are better ways of
# doing this 😉
1 |
<span style="color: #ff6600;"><strong>rename 's/~$//' "./$ext/"*;</strong></span> |
# all done after iterating through each extension type
1 |
<span style="color: #ff6600;"><strong>done</strong></span> |