使用sed以三位数值填充文件名中的数值

时间:2012-03-27 19:12:55

标签: bash sed file-rename

我将文件名传递给我的bash脚本并使用sed清理名称。一些示例文件将是:

Test 01.txt
Test v2 01.txt

我想回来:

Test 001.txt
Test v002 001.txt

这是我的剧本

#!/bin/bash

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for f in $@
do

j=`basename "$f" ".???"`
BASENAME=`basename "$f" ".???"`
DIRNAME=`dirname "$f"`

j=`echo $j |sed -e 's/\///g'`
j=`echo $j |sed -e 's/_/ /g'`
j=`echo $j |sed -e 's/^\.//'`
j=`echo $j |sed -e 's/\[[^()]*\]//g'`
j=`echo $j |sed -e 's/([^()]*)//g'`
j=`echo $j |sed -e 's/#//g'`
j=`echo $j |sed -e 's/+/\ /g'`
j=`echo $j |sed -e 's/\.\././g'`
j=`echo $j |sed -e 's/\&/and/g'`
j=`echo $j |sed -e 's/\ -/-/g'`
j=`echo $j |sed -e 's/-\ /-/g'`
j=`echo $j |sed -e 's/-{2,}/-/g'`
j=`echo $j |sed -r -e 's/\d+/sprintf("%03d",$&)/e'`
j=`echo $j |sed -e 's/\.\././g'`
j=`echo $j |sed -e "s/\'//g"`
j=`echo $j |sed -r -e 's/ {2,}/ /g'`
j=`echo $j |sed -e 's/\ \././g'`

if [ "$BASENAME" != "$j" ]; then
  mv -v "$f" "$DIRNAME"/"$j"
fi

done

这是问题行

j=`echo $j |sed -r -e 's/\d+/sprintf("%03d",$&)/e'`

正则表达式将使用重命名,但不能使用sed。

3 个答案:

答案 0 :(得分:2)

这可能适合你(GNU sed):

sed  -r 's/[0-9]+/$(printf "%03d" &)/g;s/.*/echo "&"/e' file
Test 001.txt
Test v002 001.txt

答案 1 :(得分:2)

而不是

sed -r -e 's/\d+/sprintf("%03d",$&)/e'

使用

perl -pe 's/\d+/sprintf("%03d",$&)/ge'

答案 2 :(得分:1)

根据您的评论,是的,我理解使用该方法进行调试,这是我的猜测。

这几乎一样容易,并且稍后不需要清理步骤来将关闭行和“'”字符串上下移动到下面的列表中进行调试(作为替代解决方案)。

j=$(
  echo "$j" \
  | sed '
    s/\///g
    s/_/ /g
    s/^\.//
    s/\[[^()]*\]//g
    s/([^()]*)//g
    s/#//g
    s/+/\ /g
    s/\.\././g
    s/\&/and/g
    s/\ -/-/g
    s/-\ /-/g
    s/-{2,}/-/g
    s/\.\././g
    s/'"'"'//g
    s/ {2,}/ /g
    s/\ \././g
' \
| awk '/[0-9]/{
   match( $0,/[0-9][0-9]*/ )
   begin=substr($0,1,RSTART); end=substr($0,RSTART+RLENGTH,length($0))
   num=substr($0,RSTART,RSTART+RLENGTH)
   printf("%s%03d%s", begin,num+0, end)
  }'
)

修改有可能对转义的单引号加倍,即\\'\\\',但我会使用经过验证的s/'"'"'//g { {1}}。

除非您在Solaris,AIX,HP或其他旧行unixen上使用原始bourne shell,否则请加入20世纪90年代;-)并使用$( ...)构造进行命令替换。自从1995年出版的“The New Kornshell programming Language”以来,反引号一直被弃用。

我希望这会有所帮助。