记一次 Linux 脚本八进制的坑

今天在编写一个根据文件夹名更改文件名的脚本的时候,出现了个小意外,之前之所以没碰到过,是因为较少在数字前面加0。具体的问题为,如果在数字前面加上0,在进行自加到8之后,也就是0008的时候,再进行运算,会出现 “0008: value too great for base (error token is "0008")” 的报错。

编写的脚本如下:

function ChangeFileNameFromDirName() {
    # 将所有的文件按文件夹命名
    local dir_name="${1}";
    i=1;
    ls | sort | grep "jpg" |
    while read file_name;do
      # 在编号前面补0
      set -x;
      if [ ${i} -lt 10 ]; then i=000${i}; fi
      if [ ${i} -ge 10 ] && [ ${i} -lt 100 ]; then i=00${i}; fi
      if [ ${i} -ge 100 ] && [ ${i} -lt 1000 ]; then i=0${i}; fi
      if [ ${i} -ge 1000 ]; then i=0${i}; fi
      echo -e "重命名 ${file_name} 为 ${dir_name}-${i}.jpg"
      mv "${file_name}" "${dir_name}-${i}.jpg"
      i=$((i+1));
    done
}

如上,由于有补0的操作,这是功能必须,也是造成问题的主要原因,以下是报错信息:

...
+ i=8
+ read file_name
+ set -x
+ '[' 8 -lt 10 ']'
+ i=0008
+ '[' 0008 -ge 10 ']'
+ '[' 0008 -ge 100 ']'
+ '[' 0008 -ge 1000 ']'
+ echo -e '重命名 999999999999X183-2008-1-30-004-0006.jpg 为 X183-2008-1-30-004-0008.jpg'
重命名 999999999999X183-2008-1-30-004-0006.jpg 为 X183-2008-1-30-004-0008.jpg
+ mv 999999999999X183-2008-1-30-004-0006.jpg X183-2008-1-30-004-0008.jpg
./ChangeFileName.sh: line 51: 0008: value too great for base (error token is "0008")
...

根据研究,此报错是因为变量 i 是以 0 开头的,Bash 将它识别为八进制了,所以产生了问题,需要将八进制转换为十进制来解决问题。

网上有很多通过转换成十进制来解决问题的办法,但是我试了几次感觉不是很方便,并且略难解读。故使用 bc 来先将变量前面的 0 去掉,再进行运算,问题也算圆满解决。更新后的脚本如下:

function ChangeFileNameFromDirName() {
    # 将所有的文件按文件夹命名
    local dir_name="${1}";
    i=1;
    ls | sort | grep "jpg" |
    while read file_name;do
      # 在编号前面补0
      set -x;
      if [ ${i} -lt 10 ]; then i=000${i}; fi
      if [ ${i} -ge 10 ] && [ ${i} -lt 100 ]; then i=00${i}; fi
      if [ ${i} -ge 100 ] && [ ${i} -lt 1000 ]; then i=0${i}; fi
      if [ ${i} -ge 1000 ]; then i=0${i}; fi
      echo -e "重命名 ${file_name} 为 ${dir_name}-${i}.jpg"
      mv "${file_name}" "${dir_name}-${i}.jpg"
      # 将变量i进行一次过滤,去掉前面的0,避免0008的错误
      # 0开头的数会被自动识别成八进制,故在变量大于8时,会出现报错如下:
      # 0008: value too great for base (error token is "0008")
      i=$(echo "${i}"|bc)
      i=$((i+1));
    done
}

打完收工,新知识点 get✓ !

微信扫一扫,分享到朋友圈

记一次 Linux 脚本八进制的坑