【发布时间】:2012-03-28 07:14:57
【问题描述】:
我将一个文件名传递给我的 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'`
正则表达式可以与 rename 一起使用,但不能与 sed 一起使用。
【问题讨论】:
-
多行是为了我的理智/调试过程。示例文件名是:Test 01.txt 我想将其重命名为 Test 001.txt。
-
如果
j最初是basename的结果,那么这是什么:j=`echo $j |sed -e 's/\///g'`。只有basename /会输出包含斜线的任何内容。 -
该行是在使用基本名称之前。只是尚未删除。
-
我会评论所有这些
sed过滤器。我看到您在转换链的两个不同位置有's/\.\././g'。您将两个连续的点减少为一个,然后再做一次。-字符周围的空格可以用s/ *- */-/压缩。像s/ {2,}/ /这样的东西对{m,n}的使用是无用的。使用s/ */ /或s/ \+/ /可以使用一个或多个空格对一个空格进行两个或多个空格。
标签: bash sed file-rename