题
什么是最好的方式,采用庆典,重新命名的文件的形式:
(foo1, foo2, ..., foo1300, ..., fooN)
与零填充文件的名称:
(foo00001, foo00002, ..., foo01300, ..., fooN)
解决方案
在情况下 N
不是事先固定的:
for f in foo[0-9]*; do mv $f `printf foo%05d ${f#foo}`; done
其他提示
这是不是纯粹的庆典,但是很容易的 rename
命令:
rename 's/\d+/sprintf("%05d",$&)/e' foo*
我有一个更复杂的情况下文件的名称有一个后缀以及作为前缀。我还需要执行一个减的数量从文件。
例如,我想 foo56.png
来成为 foo00000055.png
.
我希望这可以帮助如果你做的事更为复杂。
#!/bin/bash
prefix="foo"
postfix=".png"
targetDir="../newframes"
paddingLength=8
for file in ${prefix}[0-9]*${postfix}; do
# strip the prefix off the file name
postfile=${file#$prefix}
# strip the postfix off the file name
number=${postfile%$postfix}
# subtract 1 from the resulting number
i=$((number-1))
# copy to a new name with padded zeros in a new folder
cp ${file} "$targetDir"/$(printf $prefix%0${paddingLength}d$postfix $i)
done
该oneline命令,该命令我用的是这个:
ls * | cat -n | while read i f; do mv "$f" `printf "PATTERN" "$i"`; done
模式可以是例如:
- 重新命名与增量计数器:
%04d.${f#*.}
(保持原始文件的延伸) - 重新命名与增量计数与前缀:
photo_%04d.${f#*.}
(保持原来的扩展) - 重新命名与增长计数器和变化延伸到jpg:
%04d.jpg
- 重新命名与增量计数与前缀和文件basename:
photo_$(basename $f .${f#*.})_%04d.${f#*.}
- ...
你可以过滤器的文件重新命名为例 ls *.jpg | ...
你有可利用的变量 f
这是该文件的名字和 i
这是柜台上。
对于您的问题的权利的命令是:
ls * | cat -n | while read i f; do mv "$f" `printf "foo%d05" "$i"`; done
纯粹的庆典,没有外部的进程比其他的'mv':
for file in foo*; do
newnumber='00000'${file#foo} # get number, pack with zeros
newnumber=${newnumber:(-5)} # the last five characters
mv $file foo$newnumber # rename
done
下面将这样做:
for ((i=1; i<=N; i++)) ; do mv foo$i `printf foo%05d $i` ; done
编辑: 改变使用的((i=1,...)),谢谢 mweerden!
这里有一个快速解决方案,假定一个固定长度的前缀(你的"foo")和固定长度的填充。如果你需要更多的灵活性,也许这至少将是一个有用的起点。
#!/bin/bash
# some test data
files="foo1
foo2
foo100
foo200
foo9999"
for f in $files; do
prefix=`echo "$f" | cut -c 1-3` # chars 1-3 = "foo"
number=`echo "$f" | cut -c 4-` # chars 4-end = the number
printf "%s%04d\n" "$prefix" "$number"
done
我的解决方案取代了编号, 到处都在一个字符串
for f in * ; do
number=`echo $f | sed 's/[^0-9]*//g'`
padded=`printf "%04d" $number`
echo $f | sed "s/${number}/${padded}/";
done
你可以很容易地尝试,因为它只是打印文件转化名称(无文件系统操作进行的)。
说明:
循环通过的文件的列表
一个循环: for f in * ; do ;done
, 列出了所有文件和通过每个名为 $f
变量的循环体。
抓住数字符串
与 echo $f | sed
我们管变 $f
要 sed
程序。
在命令 sed 's/[^0-9]*//g'
, 部分 [^0-9]*
与修改 ^
告诉匹配相对数字0-9(不多)和然后取出它与空的替换 //
.为什么不只是删除 [a-z]
?因为文件可以含有点、破折号等。因此,我们的一切,不是数量,并得到一个数字。
接下来,我们分配的结果 number
变量。记住不放空间分配,就像 number = …
, 因为你得到的不同的行为。
我们将执行结果的命令变量包装的命令与反引号码`.
零填充
命令 printf "%04d" $number
改变格式的数量为4位并增加零如果我们的数字中含有不到4个数字。
更换的数量,以补零的数字
我们使用 sed
再次更换的命令 s/substring/replacement/
.解释我们的变量,我们使用双引号和替代变量以这种方式 ${number}
.
剧本上只是打印变换名称,所以,让我们做实际重新命名的工作:
for f in *.js ; do
number=`echo $f | sed 's/[^0-9]*//g'`
padded=`printf "%04d" $number`
new_name=`echo $f | sed "s/${number}/${padded}/"`
mv $f $new_name;
done
希望这可以帮助别人。
我花了几个小时以图了这一点。
左垫号文件:
$ ls -l
total 0
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:24 010
-rw-r--r-- 1 victoria victoria 0 Mar 28 18:09 050
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:23 050.zzz
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:24 10
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:23 1.zzz
$ for f in [0-9]*.[a-z]*; do tmp=`echo $f | awk -F. '{printf "%04d.%s\n", $1, $2}'`; mv "$f" "$tmp"; done;
$ ls -l
total 0
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:23 0001.zzz
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:23 0050.zzz
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:24 010
-rw-r--r-- 1 victoria victoria 0 Mar 28 18:09 050
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:24 10
解释
for f in [0-9]*.[a-z]*; do tmp=`echo $f | \
awk -F. '{printf "%04d.%s\n", $1, $2}'`; mv "$f" "$tmp"; done;
- 注意到反引号:
`echo ... $2}\`
(的反斜杠,\,立即以上只是分裂,一个班轮两个行为可读性) - 在环发现文件被命名为数字与大写字母的扩展:
[0-9]*.[a-z]*
- 回音,文件(
$f
)通过它awk
-F.
:awk
现场隔离,一个时期(.
):如果相匹配,分文件名为两个领域($1
=数;$2
=扩展)- 格式
printf
:印第领域($1
, ,部分数)为4位数字(%04d
),然后打印的期间,然后打印的第二个领域($2
:扩展)作为一个string(%s
).所有这一切都是分配给$tmp
变量 - 最后,移动的源文件(文件
$f
)的新的文件($tmp
)