How can I use the terminal / Linux commands to recursively search a drive for images (jpg) and copy them to my desktop, renaming all the found files using numbers. So the first time it finds should be copied to the desktop as 1.jpg, the second file should be copied as 2.jpg and 50,000th file should be copied as 50000.jpg and so on.
2 Answers
n=1; for file in $(find /media/foo/ -name '*.jpg'); do cp $file ~/Desktop/$n.jpg; n=$((n + 1)); done
There are two problems here.
- Finding a set of jpeg files.
- Copying a set of files to a target directory with sequential, numbered names.
For the first problem the obvious and correct solution is find
, which fortunately makes this very easy.
find / -type f -iregex '.*\.jpe?g$'
Of course this could be made more sophisticated if you wanted to e.g. do type detection with file
instead of by extension.
The second problem is sequential copying. A simple counter is all that is necessary to make this work.
n=1
cp "$source" "$dest/$n.jpeg"
n=$((n + 1 ))
Doing this inside a loop, of course, where $source
changes on each iteration.
Putting it all together
#!/usr/bin/env bash
usage() {
echo "$0: usage: $0 [source directory] [destination directory]"
}
if [ ${#@} -ne 2 ] ; then
usage
exit
fi
scan="$1"
dest="$2"
if [ ! -d "$scan" ] ; then
usage
printf "\nspecified source does not exist or is not a directory\n"
exit
fi
if [ ! -d "$dest" ] ; then
usage
printf "\nspecified destination does not exist or is not a directory\n"
exit
fi
n=1
while read -r -d $'\0' source ; do
cp "$source" "$dest/$n.jpeg"
n=$((n + 1 ))
done < <(find "$scan" -type f -regextype posix-extended -iregex '.*\.jpe?g$' -print0)
Portability note: -regextype
is a GNU find extension; without it -iregex
may not match file names containing newlines.