Bash 将文件夹中的文件重命名为序列号
我想将目录中的文件重命名为序列号。基于文件的创建日期Bash 将文件夹中的文件重命名为序列号,bash,rename,batch-rename,Bash,Rename,Batch Rename,我想将目录中的文件重命名为序列号。基于文件的创建日期 例如sadf.jpg到0001.jpg,wrjr3.jpg到0002.jpg等等,前导零的数量取决于文件总量(如果不需要,则不需要额外的零)。尝试使用循环、let和printf作为填充: a=1 for i in *.jpg; do new=$(printf "%04d.jpg" "$a") #04 pad to length of 4 mv -i -- "$i" "$new" let a=a+1 done 使用-i标志可以防止
例如
sadf.jpg
到0001.jpg
,wrjr3.jpg
到0002.jpg
等等,前导零的数量取决于文件总量(如果不需要,则不需要额外的零)。尝试使用循环、let
和printf
作为填充:
a=1
for i in *.jpg; do
new=$(printf "%04d.jpg" "$a") #04 pad to length of 4
mv -i -- "$i" "$new"
let a=a+1
done
使用
-i
标志可以防止自动覆盖现有文件。我喜欢gauteh的解决方案,因为它简单,但它有一个重要的缺点。在数千个文件上运行时,您可能会收到“argumentlist too long”消息(),其次,脚本可能会变得非常慢。在我的例子中,在大约36000个文件上运行它,脚本每秒移动大约一个项目!我不太清楚为什么会发生这种情况,但我从同事那里得到的规则是“find
是你的朋友”
要计算项目和生成命令,请使用。不过,请注意主要区别。默认情况下,
find
搜索当前目录及其子目录中的文件,因此确保仅在必要时限制对当前目录的搜索(使用manfind
查看如何进行)。在OSX上使用Pero的解决方案需要一些修改。我用过:
find . -name '*.jpg' \
| awk 'BEGIN{ a=0 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' \
| bash
注:反斜杠用于行延续
2015年7月20日编辑:
合并@klaustopher的反馈,引用
mv
命令的\%s\“
参数,以支持带有空格的文件名。此脚本将根据Mac OS bash上的创建日期对文件进行排序。我用它来批量重命名视频。只需更改扩展名和名称的第一部分
ls -trU *.mp4| awk 'BEGIN{ a=0 }{ printf "mv %s lecture_%03d.mp4\n", $0, a++ }' | bash
若要在所有情况下工作,请为名称中有空格的文件添加\”
find . -name '*.jpg' | gawk 'BEGIN{ a=1 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' | bash
使用“重命名”命令
或
如果您的
重命名
不支持-N
,可以执行以下操作:
ls -1 --color=never -c | xargs rename -n 's/.*/our $i; sprintf("%04d.jpg", $i++)/e'
编辑要从给定的数字开始,您可以使用下面的代码(看起来有些难看),只需将123替换为您想要的数字即可:
ls -1 --color=never -c | xargs rename -n 's/.*/our $i; if(!$i) { $i=123; } sprintf("%04d.jpg", $i++)/e'
这将按创建时间顺序列出文件(最新的是,首先将-r
添加到ls以进行反向排序),然后发送此文件列表以进行重命名。重命名使用正则表达式中的perl代码格式化和递增计数器
但是,如果您正在处理带有EXIF信息的JPEG图像,我建议您使用exiftool
这来自“重命名示例”下的
exiftool'-FileName再次使用Pero的解决方案,几乎不做任何修改,因为find
将按照项目存储在目录项中的顺序遍历目录树。这将(大部分)在同一台机器上运行时保持一致,基本上是“文件/目录创建顺序”“如果没有删除
然而,在某些情况下,您需要获得一些逻辑顺序,例如,按名称,这在本例中使用
find -name '*.jpg' | sort -n | # find jpegs
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | # build mv command
bash # run that command
我有一个类似的问题,为此写了一个shell脚本。我决定把它贴出来,不管有多少好的答案已经贴出来了,因为我认为它可以帮助别人。请随意改进它
@Gnutt您想要的行为可以通过键入以下内容来实现:
./numerate.sh -d <path to directory> -o modtime -L 4 -b <startnumber> -r
/numerate.sh-d-o modtime-L 4-b-r
如果省略选项-r
,则仅模拟铰孔(应有助于测试)
otion L描述目标编号的长度(将用前导零填充)
还可以使用选项-p
-s
添加前缀/后缀
如果有人想在对文件编号之前对其进行数字排序,只需删除-o modtime
选项。这里是另一个使用“重命名”命令的解决方案:
假设目录中有这些文件,按创建顺序列出,第一个是最旧的:
a.jpg
b.JPG
c.jpeg
d.tar.gz
e
然后,ls-1cr
精确地输出上面的列表。然后可以使用重命名:
ls-1cr | xargs rename-n's/^[^\.]*(\..*)?$/我们的$i;sprintf(“%03d$1”,$i++)/e'
哪个输出
rename(a.jpg,000.jpg)
重命名(b.JPG,001.JPG)
重命名(c.jpeg,002.jpeg)
重命名(d.tar.gz,003.tar.gz)
在(eval 4)第1行的串联(.)或字符串中使用未初始化的值$1。
重命名(e,004)
对于没有扩展名的文件显示警告“使用未初始化值[…]”;你可以忽略它
从重命名
命令中删除-n
,以实际应用重命名
这个答案的灵感来自于。它忽略了Gnutt根据文件总量设置前导零数的要求。要对一个文件夹中的6000个文件重新编号,可以使用ACDsee程序的“重命名”选项
要定义前缀,请使用以下格式:####“*”
然后设置起始编号并按Rename,程序将使用序列号重命名所有6000个文件。大多数其他解决方案将覆盖已命名为数字的现有文件。如果运行脚本,添加更多文件,然后再次运行脚本,这尤其是一个问题
此脚本首先重命名现有的数字文件:
#!/usr/bin/perl
use strict;
use warnings;
use File::Temp qw/tempfile/;
my $dir = $ARGV[0]
or die "Please specify directory as first argument";
opendir(my $dh, $dir) or die "can't opendir $dir: $!";
# First rename any files that are already numeric
while (my @files = grep { /^[0-9]+(\..*)?$/ } readdir($dh))
{
for my $old (@files) {
my $ext = $old =~ /(\.[^.]+)$/ ? $1 : '';
my ($fh, $new) = tempfile(DIR => $dir, SUFFIX => $ext);
close $fh;
rename "$dir/$old", $new;
}
}
rewinddir $dh;
my $i;
while (my $file = readdir($dh))
{
next if $file =~ /\A\.\.?\z/;
my $ext = $file =~ /(\.[^.]+)$/ ? $1 : '';
rename "$dir/$file", sprintf("%s/%04d%s", $dir, ++$i, $ext);
}
美在一行:
ls -v | cat -n | while read n f; do mv -n "$f" "$n.ext"; done
您可以使用.png
、.jpg
等更改.ext
。一个非常简单的bash one liner,它保留原始扩展名,添加前导零,并在OSX中工作:
num=0; for i in *; do mv "$i" "$(printf '%04d' $num).${i#*.}"; ((num++)); done
简化版的按时间排序,仅限于jpg、前导零和基本名称(如果您可能需要):
(全部在一行上,没有\
)佩罗的回答把我带到这里:)
我想相对于时间重命名文件,因为图像查看器没有按时间顺序显示图像
ls -tr *.jpg | # list jpegs relative to time
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | # build mv command
bash # run that command
在OSX上安装自制的重命名脚本:
brew install rename
然后你就可以轻松地做到这一点:
rename -e 's/.*/$N.jpg/' *.jpg
#!/usr/bin/perl
use strict;
use warnings;
use File::Temp qw/tempfile/;
my $dir = $ARGV[0]
or die "Please specify directory as first argument";
opendir(my $dh, $dir) or die "can't opendir $dir: $!";
# First rename any files that are already numeric
while (my @files = grep { /^[0-9]+(\..*)?$/ } readdir($dh))
{
for my $old (@files) {
my $ext = $old =~ /(\.[^.]+)$/ ? $1 : '';
my ($fh, $new) = tempfile(DIR => $dir, SUFFIX => $ext);
close $fh;
rename "$dir/$old", $new;
}
}
rewinddir $dh;
my $i;
while (my $file = readdir($dh))
{
next if $file =~ /\A\.\.?\z/;
my $ext = $file =~ /(\.[^.]+)$/ ? $1 : '';
rename "$dir/$file", sprintf("%s/%04d%s", $dir, ++$i, $ext);
}
ls -v | cat -n | while read n f; do mv -n "$f" "$n.ext"; done
num=0; for i in *; do mv "$i" "$(printf '%04d' $num).${i#*.}"; ((num++)); done
ls -t *.jpg | cat -n | \
while read n f; do mv "$f" "$(printf thumb_%04d.jpg $n)"; done
ls -tr *.jpg | # list jpegs relative to time
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | # build mv command
bash # run that command
brew install rename
rename -e 's/.*/$N.jpg/' *.jpg
rename -e 's/.*/photo-$N.jpg/' *.jpg
ls -1tr | rename -vn 's/.*/our $i;if(!$i){$i=1;} sprintf("%04d.jpg", $i++)/e'
ls -v | gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | bash
rename --counter-format 000001 --lower-case --keep-extension --expr='$_ = "$N" if @EXT' *
Here i replaced spaces , ' ' in a file name with '_' for all jpg files
#! /bin/bash
rename 'y/ /_/' *jpg #replacing spaces with _
let x=0;
for i in *.jpg;do
let x=(x+1)
mv $i $x.jpg
done
if [ ! -r _e -a ! -r _c ]; then echo 'pdf' > _e; echo 1 > _c ;find . -name "*.$(cat _e)" -print0 | xargs -0 -t -I{} bash -c 'mv -n "{}" $(cat _c).$(cat _e);echo $[ $(cat _c) + 1 ] > _c'; rm -f _e _c; fi
a=1
# reset the variable if you
# want to use the script 2nd
# time in the same directory
for i in *.jpg; do
mv -- "$i" "walp_$a.jpg"
a=`expr $a + 1`
done