I have a bunch of image files named as 1.jpg
in several directories I want to copy that into another.
I tried using the below command (consider 100 folders)
find folder/{1..100} -type f -name '1.*' -exec cp --backup=numbered "{}" folder/new/ \;
but the file extension get changed as below
1.jpg.~1~
1.jpg.~2~
1.jpg.~3~
...
I am expecting my output should look something like below
1.~1~.jpg
1.~2~.jpg
1.~3~.jpg
...
(or)
1(1).jpg
1(2).jpg
1(3).jpg
...
Note: I am using {1..100}
so that folder order starts from 1, 2, 3, 4...100
and not as 1, 10, 11,...100, 2, 20, 21, 22...
Is there any way I could find and copy images without changing the file extension?
Thank you in advance!
CodePudding user response:
Do you accept a solution in two times?
- Run your
find
command - Run this command:
for f in folder/new/*.~*~; do
idx="${f##*.}";
new=${f%.${idx}};
idx="${idx//\~/}";
ext="${new##*.}";
new="${new%.${ext}}";
new="${new}(${idx}).${ext}";
echo mv "$f" "$new";
done
Only based on bash remove %
, #
, %%
and ##
matching patterns.
- get index pattern from original filename (f)
- new filename (new) is original filename without index extension (~*~)
- remove
~
characters in index token (idx) - get original filename extension (ext)
- remove original filename extension in new filename
- create new filename (with format as you want)
- rename original filename to new filename
Notes:
- Remove new line characters if you want (just here for presentation)
- After test, remove
echo
beforemv
command.
CodePudding user response:
Assuming you want to use the subfolder name (number) as a suffix to the new file name, would you please try:
#!/bin/bash
folder="folder" # directory name
base="1" # basename of the jpg file
ext="jpg" # extention of the jpg file
new="new" # directory name for the "new" files
mkdir -p "$folder/$new" # create "new" directory if nonexistent
while IFS= read -r -d "" f; do
n=${f#*$folder/}; n=${n%/$base.$ext}
echo cp -i -- "$f" "$folder/$new/$base($n).$ext"
done < <(find "$folder" -type f -regex "$folder/[0-9] /$base\.$ext" -print0)
find "$folder" -type f -regex "$folder/[0-9] /$base\.$ext"
finds all numbered folders which contains "1.jpg". You do not have to specify the range between 1 and 100.-print0
option uses a null character to delimit filenames. It is useful to protect filenames which may contain special characters such as blank characters.- The output of
find
command, matched filenames delimited by null characters, is redirected to theread
command within thewhile
loop. - The
-d ""
option to theread
command splits the input on null characters corresponding to-print0
. n=${f#*$folder/}; n=${n%/$base.$ext}
assignsn
to the subfolder name which contains the jpg file."$folder/$new/$base($n).$ext"
constructs the new filename rearranging the substrings.
If the output of the echo
command looks okay, drop echo
.