Comments on Rename multiple files which have a variable suffix
Parent
Rename multiple files which have a variable suffix
I compressed some JPEGs with curtail
it messed up the filenames. It was supposed to only add -min
at the end but ended up adding a random string after the extension 😠:
prs@PC:/DOWNLOADS/Pictures$ find . -type f
./IMG_20230917_093726_2-min.jpg-U2XlUA <<< To rename "[...]_2-min.jpg"
./IMG_20230917_093726_2.jpg - Don't do anything
./IMG_20230917_093738_3-min.jpg-H39QsD <<< To rename "[...]_3-min.jpg"
./IMG_20230917_093738_3.jpg - Don't do anything
./IMG_20230917_094057_1-min.jpg-AbxJMt <<< To rename "[...]_1-min.jpg"
./IMG_20230917_094057_1.jpg - Don't do anything
How can I remove the random string for each -min
file?
I already have a find
command that gets the -min
files while excluding the pictures I don't want to touch:
find . -name "*-min.jpg-*"
Post
find . -type f -print0 \
| grep -z -- '-min.jpg-[[:alnum:]]*$' \
| while IFS= read -r -d '' f; do
find "$f" -print0 \
| sed -z 's/-min.jpg-[[:alnum:]]*$/-min.jpg/' \
| xargs -0 mv "$f";
done;
Or, if you prefer a one-liner:
find . -type f -print0 | grep -z -- '-min.jpg-[[:alnum:]]*$' | while IFS= read -r -d '' f; do find "$f" -print0 | sed -z 's/-min.jpg-[[:alnum:]]*$/-min.jpg/' | xargs -0 mv "$f"; done;
The code above is hardened against malicious, broken, or otherwise non-portable file names. That makes it slightly more complex than necessary.
Never use whitespace in file names. They are non-portable. See POSIX: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282.
For the hardened version, find(1)'s -print0
and xargs(1)'s -0
are common enough that don't need explanation (do an online search). grep(1)'s and sed(1)'s -z
and read(1)'s -r
are less common, but still common enough. read(1)'s -d ''
is a trick explained here: https://stackoverflow.com/questions/9612090/how-to-loop-through-file-names-returned-by-find#comment98776168_9612232.
Here's a simpler version, which you can run if you know your file names are portable:
find . -type f \
| grep -- '-min.jpg-[[:alnum:]]*$' \
| while read f; do
echo $f \
| sed 's/-min.jpg-[[:alnum:]]*$/-min.jpg/' \
| xargs mv $f;
done;
find . -type f |
:
Find files
| grep -- '-min.jpg-[[:alnum:]]*$' |
:
Filter those that have interesting file names.
--
is necessary to avoid interpreting the pattern as an option to grep(1).
| while read f; do
:
For each path name (each line), store the path name in $f
, and run the nested commands on it.
echo $f |
:
Echo the full path name.
| sed 's/-min.jpg-[[:alnum:]]*$/-min.jpg/' |
:
Remove the part of the file name that we don't like.
| xargs mv $f;
:
Move the file $f (this was the old path name), to the path resulting of the previous filter.
done;
:
Have a nice sleep :)
0 comment threads