简体   繁体   中英

Rename all files to with four-digit padding, sort by the number values in the filename. bash

In other words, The file with the lowest index should map to 0001.jpg, and the second lowest index should map to 0002.jpg. Something like this:

DSCN-1009.JPG --> 1009.JPG
DSCN-1010.JPG --> 1010.JPG
DSCN-101.JPG --> 0101.JPG
DSCN-102.JPG --> 0102.JPG

or

DSCN-1.JPG --> 0001.JPG
DSCN-2.JPG --> 0002.JPG
DSCN-3.JPG --> 0003.JPG
DSCN-4.JPG --> 0004.JPG

I have this code that renames all files with four-digit padding.

X=1;
for i in *; do                       
  mv "$i" "$(printf %04d.%s "${X%.*}" "${i##*.}")"                      
  let X="$X+1"
done

but sorting of the files is off as it outputs like this (this is not what I want):

DSCN-1009.JPG --> 0009.JPG
DSCN-1010.JPG --> 0010.JPG
DSCN-101.JPG --> 0011.JPG
DSCN-102.JPG --> 0012.JPG

This is based on your script but just changing how the numbers are computed:

for i in *
do
    mv "$i" "$(printf %04d.%s "${i//[^0-9]/}" "${i##*.}")"
done

The key is the bash construct ${i//[^0-9]/} . This removes all non-numbers from the filename. So, if i=DSCN-101.JPG , then ${i//[^0-9]/} becomes just 101 . The printf command formats the number zero-padded to four digits.

${i//[^0-9]/} is called pattern substitution. In its general form, it looks like ${parameter//pattern/string} where parameter is the variable name. pattern is some regular expression. Everywhere that the regular expression pattern occurs in variable , it is replaced by string . In our case, the regular expression is [^0-9] which matches all non-numbers and string is the empty string. Thus, all non-numbers are replaced with the empty string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM