Answer the question
In order to leave comments, you need to log in
How to rename files using a mask as simply and quickly as possible?
Hello dear.
How do I change filenames from
1, 2, 3, ... 10, 11, 12, ... 100, 101, 102
to
001, 002, 003, ... 010, 011, 012, ... 100, 101, 102
(1)*, (2)*, (3)*, ... (100)*, (101)*
and the mask of file names like *№1, *№2, *№3, ... *№100, *№101, *№102
.
Answer the question
In order to leave comments, you need to log in
Well, on bash manually it's easy:
for i in {1..99}; do a=00$i; mv $i ${a: -3}; done
1. Make a list of files you are interested in using the glob or pathlib module.
2. Using the regular expression "\d+" (module re), you extract sequences of digits from file names. If there are several, you will have to come up with a criterion for which one to take (for example, the last one). You determine the maximum number of digits.
3. Iterate through the list of names again with re.sub() . The second argument to re.sub() can be not only a string to replace, but also a function - you just make a function that pads the input string with zeros to the desired width and returns it.
4. If the new line (with replacement) differs from the original one, then rename the file with the original name to the file with the new name, otherwise you leave it as it is.
Came up with a working solution.
It should work with different filenames in the current directory, as long as there is only one piece with a number in the file.
That is, it will cope with such a set of files: file1.jpg file02.jpg file0035.jpg 36file.jpg, if only the numbers do not intersect
And it will NOT cope with this: file1_1.jpg 01_file_02.jpg
max=$(ls -1 | grep -oP "[0-9]*"|sort -n|tail -n1)
length=$(sed "s/^0*//g"<<<"$max"|xargs expr length)
echo "Max number found: [$max], max length: [$length]"
ls -1|while read oldname; do
oldnum="$(grep -oP "[0-9]*"<<<"oldname")"
newnum=$(printf "%0${length}d" $(sed "s/^0*//g"<<<"$oldnum"))
newname=$(sed "s/$oldnum/$newnum/g"<<<"$oldname")
if [ -f "$newname" ]; then
echo "Kinly check the following files manually: $oldname $newname"
else
echo "Renaming [$oldname] to [$newname]"
# mv "$oldname" "$newname"
done
Well, here is the essence, but what more specifically you need for other cases, I did not understand.
The easiest option is to do it just for the find, the only thing is that in your example there are only two options, so there is no need to make any loops, it’s easier to run the condition twice. For tests, replace mv with cp or test daddy.
find . -type f -name '[0-9][0-9]\.txt' -exec bash -c 'mv $0 0${0#./}' {} \;
find . -type f -name '[0-9]\.txt' -exec bash -c 'mv $0 00${0#./}' {} \;
[[email protected] test]$ ls
10.txt 1.txt 2.txt 333.txt
[[email protected] test]$ ls
001.txt 002.txt 010.txt 333.txt
find
-search is recursive .
where -type f
- only files -name
- the file name in this regular routine -exec
run with found, the option of find -bash -
bash itself (since we need to remove ./ from the file name and find itself can do this, but we need to leave the previous option for mv and here already all ) {}
substitute the output of find into exec \;
escape and close find Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question