我正试图重命名模式A_B_x.csv中的文件,其中x在(1..10)中,我想要的是确切地拥有A_B_x+10.csv,例如,如果文件是A_B_1.csv我想要A_B_11.csv。我是bash的新手,还没有找到解决方案,我试过:
for f in *.csv;
do
newname=`echo $f | sed 's/1.csv/11.csv/g'`;
mv $f $newname;
done
用11替换所有1,但我不确定如何推广它,所以它适用于所有数字。有人有什么主意吗?
使用bash内置的参数扩展可以很简单地做到这一点。首先使用fn="${j%.csv}"
从文件名中删除扩展名。保存没有数字的基本文件名为base="${j%_*}"
。用ext="${j##*.}"
保存分机号,最后用num="${fn##*_}"
隔离号码
现在只需将10
添加到数字,num=$((num+10))
并将文件名放回一起,new="${base}_${num}.${ext}"
然后将j
移动到new
。
你可以这样做:
for j in A_B*; do
fn="${j%.csv}" ## filename w/o extension
base="${j%_*}" ## base filename w/o number
ext="${j##*.}" ## save extension
num="${fn##*_}" ## isolate number
num=$((num+10)) ## add 10 to number
new="${base}_${num}.${ext}" ## reconstitute filename w/new number
echo "$j -> $new" ## output result
# mv "$j" "$new" ## **Uncomment** to actually perform the move
done
Bash提供了很多很多有用的参数展开,与从字符串的前面(开始)和后面(结束)修剪相关的一组是:
${var#pattern} Strip shortest match of pattern from front of $var
${var##pattern} Strip longest match of pattern from front of $var
${var%pattern} Strip shortest match of pattern from back of $var
${var%%pattern} Strip longest match of pattern from back of $var
(注意:模式可以包含正常的通配字符,如'*'
)
使用/输出示例
如果当前目录中有文件名A_B_1.csv
到A_B_5.csv
,结果将是:
A_B_11.csv
A_B_12.csv
A_B_13.csv
A_B_14.csv
A_B_15.csv
请尝试以下操作:
for f in *.csv; do
num=$(( ${f//[^0-9]} + 10 ))
mv "$f" "$(sed -E 's/([^0-9]+)[0-9]+(.+)/1'"$num"'2/' <<< "$f")"
done
${f//[^0-9]}
从变量$f
中提取数字num=$(( ${f//[^0-9]} + 10 ))
将num赋值给数字+ 10。- "$ (sed - e ' s/([^ 0 - 9] +)[0 - 9] +(+)/ 1"num"美元;' 2/' & lt; & lt; & lt;"f"美元)";返回 文件名称,编号替换为
$num
。(替代)
如果perlrename
命令可用,您还可以这样说:
rename 's/(d+)/$& + 10/e' *.csv
请注意有两个不同的rename
命令。
您不需要sed
(当然您可以使用它)。只使用bash:
pre="${f%_*}"
tmp="${f##*_}"
num="${tmp%.csv}"
new="${pre}_$((num+10)).csv"