I have a small bash script. It is meant to run in a directory that has image files and video files. It then creates two subdirectories Vids and Pics and is supposed to move all the files into those two directories appropriately.
But when I run it the directories get created but no files are either copied or moved. What did I do wrong? Any bash experts here?
#!/bin/bash
echo "This script will check for the existence of 'Vids' and 'Pics' subdirectories and create them if they do not exist. It will then move all image files into 'Pics' and all video files into 'Vids'. Do you wish to proceed? (y/n)"
read proceed
if [ $proceed == "y" ]; then
if [ ! -d "Vids" ]; then
mkdir Vids
fi
if [ ! -d "Pics" ]; then
mkdir Pics
fi
find . -name "*.jpg" -o -name "*.jpeg" -o -name "*.png" -o -name "*.gif" -exec mv {} Pics/ \;
find . -name "*.mp4" -o -name "*.avi" -o -name "*.mkv" -o -name "*.wmv" -exec mv {} Vids/ \;
echo "Image files have been moved to 'Pics' and video files have been moved to 'Vids'."
else
echo "Exiting script."
fi
I don’t use find much but I think this should do it.
#!/bin/bash
echo "This script will check for the existence of 'Vids' and 'Pics' subdirectories and create them if they do not exist. It will then move all image files into 'Pics' and all video files into 'Vids'. Do you wish to proceed? (y/n)"
read proceed
if [ $proceed == "y" ]; then
if [ ! -d "Vids" ]; then
mkdir Vids
fi
if [ ! -d "Pics" ]; then
mkdir Pics
fi
find . \( -name "*.jpg" -o -name "*.jpeg" -o -name "*.png" -o -name "*.gif" \) -exec mv "{}" Pics/ \;
find . \( -name "*.mp4" -o -name "*.avi" -o -name "*.mkv" -o -name "*.wmv" \) -exec mv "{}" Vids/ \;
echo "Image files have been moved to 'Pics' and video files have been moved to 'Vids'."
else
echo "Exiting script."
fi
The script could do with improving, for instance you say you’ve moved files even if no files were found/moved.
Personally I would have simply not bothered with find, but use move (mv), if the files were there they would be moved to the correct directory, otherwise move (mv) would simply fail, and the script would continue to the next instruction.
Should check the return code/exit status of commands, even mkdir.
Add options to read -n 1 -p 'Enter [Y|n]: '
Change if [ "${proceed:-n}" == 'y' ]
For help type help read on the command line.
I normally use the double bracket keyword.
For help type help [[ or man bash. The command type -a [[ shows it is a keyword.
Alternative: shopt -s extglob ; mv *(*.jpg|*.png|*.gif) dir
To debug a script use set -xv at the beginning of your script.
Could you try to add maxdetph -1 type -f to the find command and remove the parentheses, using -iname instead of -name which allows the ignore case to the filename?
find . -maxdepth 1 -type f -iname “^.jpg” -o -iname “.jpeg" -o -iname ".png” -o -iname “*.gif” -exec mv { } Pics/ ;
If your point is that the find command works without brackets then that’s because the default action is to print the filename, this applies to all matches (each -iname).
When you apply an action such as -exec it no longer uses the default.
# if jpg do something elif png do something-else
find . -iname "*.jpg" -exec echo {} jpg \; -o -iname "*.png" -exec echo {} png \;
# if jpg do nothing elif png do something
find . -iname "*.jpg" -o -iname "*.png" -exec echo {} png \;
# if jpg or png do something
find . \( -iname "*.jpg" -o -iname "*.png" \) -exec echo {} both \;