我将文件名传递给我的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。
答案 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”以来,反引号一直被弃用。
我希望这会有所帮助。