我想将目录中的文件重命名为连续数字。基于文件的创建日期。
例如sadf.jpg
to 0001.jpg
,wrjr3.jpg
to 0002.jpg
等等,前导零的数目取决于文件的总数(如果不需要,则不需要额外的零)。
我想将目录中的文件重命名为连续数字。基于文件的创建日期。
例如sadf.jpg
to 0001.jpg
,wrjr3.jpg
to 0002.jpg
等等,前导零的数目取决于文件的总数(如果不需要,则不需要额外的零)。
Answers:
尝试使用循环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
标志可防止自动覆盖现有文件。
printf -v new "%04d.jpg" ${a}
可以将值放入变量中。并((a++))
增加变量。另外,这不会按照创建日期的顺序进行操作,也不会最小化OP指定的填充。但是,应该注意,Linux / Unix不存储创建日期。
mv -- "$i" "$new"
正确处理以破折号开头的源文件名。mv
照原样,将尝试解析诸如标志集合之类的文件名。
-i
应该将其包含在答案中,并相应地重写注释。这样会更安全。:(
美女合一:
ls -v | cat -n | while read n f; do mv -n "$f" "$n.ext"; done
您可以更改.ext
用.png
,.jpg
等等。
ls | cat -n | while read n f; do mv "$f" `printf "%04d.extension" $n`; done
填充数字为零
-n
到mv命令以防止意外覆盖文件。很难发现这一点!
ls -1prt | grep -v "/$" | cat -n | while read n f; do mv -n "${f}" "$(printf "%04d" $n).${f#*.}"; done
结果:(1)按修改顺序排序,后面的文件带有后面的索引;(2)忽略目录-而不是递归的;(3)填充索引;(4)保持原始扩展名。
我喜欢gauteh的解决方案,因为它简单易用,但它有一个重要的缺点。当在成千上万个文件上运行时,您可能会收到“参数列表过长”的消息(有关更多信息),其次,脚本会变得非常慢。就我而言,在大约36.000个文件上运行它,脚本移动了大约。每秒一件!我不太确定为什么会这样,但是我从同事那里得到的规则是“ find
是你的朋友”。
find -name '*.jpg' | # find jpegs
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | # build mv command
bash # run that command
为了计数项目和构建命令,使用了gawk。请注意主要区别。默认情况下find
,在当前目录及其子目录中搜索文件,因此,请确保在必要时仅在当前目录中进行搜索(man find
以了解操作方法)。
NR
用于较短的命令。gawk '{ printf "mv %s %04d.jpg\n", $0, NR }'
$(rm -rf /).jpg
。
for
回路不考虑每个文件1秒,严格地说。从文件系统中获取36,000个文件名,然后合理快速地遍历它们,需要花费很长时间。许多文件系统都存在大型目录问题,无论您运行的是哪种精确命令。但通常find
会比Shell通配符更快,因为它必须获取并排序匹配文件列表。
使用“重命名”命令
rename -N 0001 -X 's/.*/$N/' *.jpg
要么
rename -N 0001 's/.*/$N.jpg/' *.jpg
rename
(Linux Mint 13)没有-N
选择。
rename
命令,但我从来不知道-N
!谢谢!
rename
。@Bostrot发布的链接是另一个重命名工具,似乎@RomanRhrnNesterov使用了该工具。¶对于rename
Peder Stray和Larry Wall的所有用户(perl-rename
arch Linux上的软件包rename
和debian / ubuntu上的软件包):您可以定义$N
自己:perl-rename '$N=sprintf("%04d",++$N); s/.*/$N.jpg/' *.jpg
在OSX上使用Pero解决方案需要进行一些修改。我用了:
find . -name '*.jpg' \
| awk 'BEGIN{ a=0 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' \
| bash
注意:反斜杠用于继续行
编辑2015年7月20日:
合并@klaustopher的反馈以引用命令的\"%s\"
参数,mv
以支持带空格的文件名。
$(rm -rf /).jpg
。
mv
。如果您有一个名为ie的文件,则some thing.jpg
脚本将失败。这就是我所使用的:find . -name '*.jpg' | awk 'BEGIN{ a=0 }{ printf "mv \"%s"\ wallpaper-%04d.jpg\n", $0, a++ }' | bash
-maxdepth 1
只在当前目录中的jpgs上工作,因为安全比后悔好。
ls -1 *.jpg
而不是查找,否则将不会进行排序。或添加|sort|
之前AWK
一个非常简单的bash one衬里,可以保留原始扩展名,添加前导零,并且还可以在OSX中使用:
num=0; for i in *; do mv "$i" "$(printf '%04d' $num).${i#*.}"; ((num++)); done
9.ext
在之前进行排序11.ext
,但是其他工具(例如ls
)也不会进行排序。
要在所有情况下都可以工作,请在名称中带有空格的文件前加上\“
find . -name '*.jpg' | gawk 'BEGIN{ a=1 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' | bash
$(rm -rf /)
因此仍喜欢使用扩展名。
如果您rename
不支持-N
,则可以执行以下操作:
ls -1 -c | xargs rename -n 's/.*/our $i; sprintf("%04d.jpg", $i++)/e'
编辑要以给定的数字开头,可以使用下面的代码(看起来有些难看),只需将123替换为所需的数字即可:
ls -1 -c | xargs rename -n 's/.*/our $i; if(!$i) { $i=123; } sprintf("%04d.jpg", $i++)/e'
这按创建时间顺序列出文件(最新的,添加 -r
到ls进行反向排序),然后发送此文件列表进行重命名。重命名使用正则表达式中的perl代码来格式化和递增计数器。
但是,如果您要处理带有EXIF信息的JPEG图像,我建议 exiftool
这来自exiftool文档的 “重命名示例”下
exiftool '-FileName<CreateDate' -d %Y%m%d_%H%M%S%%-c.%%e dir
Rename all images in "dir" according to the "CreateDate" date and time, adding a copy number with leading '-' if the file already exists ("%-c"), and
preserving the original file extension (%e). Note the extra '%' necessary to escape the filename codes (%c and %e) in the date format string.
rename
?
在OSX上,从Homebrew安装重命名脚本:
brew install rename
然后,您可以非常轻松地做到这一点:
rename -e 's/.*/$N.jpg/' *.jpg
或添加一个不错的前缀:
rename -e 's/.*/photo-$N.jpg/' *.jpg
Global symbol "$N" requires explicit package name (did you forget to declare "my $N"?) at (user-supplied code).
我有一个类似的问题,因此写了一个shell脚本。我决定发布它,而不管已经发布了许多好的答案,因为我认为这可能对某人有所帮助。随时进行改进!
@Gnutt可以通过键入以下命令来实现所需的行为:
./numerate.sh -d <path to directory> -o modtime -L 4 -b <startnumber> -r
如果-r
忽略该选项,则扩孔将仅被模拟(对测试很有帮助)。
选项L描述了目标编号的长度(将用前导零填充),也可以在选项中添加前缀/后缀-p <prefix>
-s <suffix>
。
如果有人希望在编号之前对文件进行数字排序,则只需删除该-o modtime
选项即可。
让我们假设我们在目录中按创建顺序列出了这些文件,第一个是最旧的:
a.jpg
b.JPG
c.jpeg
d.tar.gz
e
然后ls -1cr
精确输出上面的列表。然后,您可以使用rename
:
ls -1cr | xargs rename -n 's/^[^\.]*(\..*)?$/our $i; sprintf("%03d$1", $i++)/e'
哪个输出
rename(a.jpg, 000.jpg)
rename(b.JPG, 001.JPG)
rename(c.jpeg, 002.jpeg)
rename(d.tar.gz, 003.tar.gz)
Use of uninitialized value $1 in concatenation (.) or string at (eval 4) line 1.
rename(e, 004)
对于没有扩展名的文件,显示警告“使用未初始化的值[…]”。您可以忽略它。
-n
从rename
命令中删除以实际应用重命名。
此答案受卢克(Luke)2014年4月的回答启发。它忽略了Gnutt要求根据文件总数设置前导零的数目的要求。
ls -1tU
为创建时间来调整订单。它还需要rename
安装,而我没有。
再次使用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
blahblah; rm -r * blahblah.jpg
怎么办?
对我来说,答案的组合非常有效:
ls -v | gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | bash
ls -v
有助于正确订购1 10 9:1 9 10顺序,避免jpg JPG jpeg的文件扩展名问题gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }'
用4个字符和前导零重新编号。通过避免使用mv,我不会无意间尝试使用相同的数字来覆盖已经存在的任何内容。bash
执行请注意@xhienne所说的内容,将未知内容传递给bash有安全隐患。但这不是我的情况,因为我正在使用扫描的照片。
您也可以使用ls
ls *.JPG| awk 'BEGIN{ a=0 }{ printf "mv %s gopro_%04d.jpg\n", $0, a++ }' | bash
blahblah; rm -r * blahblah.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);
}
此oneliner列出当前目录中的所有文件,并以相反的顺序按创建时间戳排序(意味着最旧的文件位于开头),并根据文件数量的要求自动重命名为尾随零。文件扩展名将被保留。
多年来,我通常只有一个文件夹用于存放手机图片和电影。应用此命令,我的图片和电影就可以在电视或存档上以正确的顺序进行幻灯片放映了。
请注意,如果文件名冲突,则将丢失文件。因此,首先将其重命名为类似的名称temp001.jpg
,然后执行最终文件名。
DIGITS=$(ls | wc -l | xargs | wc -c | xargs); ls -tcr | cat -n | while read n f; do mv "$f" "$(printf "%0${DIGITS}d" $n).${f##*.}"; done
ls
最好不要避免运行一次,而应该运行两次,但是我没有深入研究它。
ls
,因此这就是为什么需要两个的原因。3.这样的命令是单发命令,并不意味着要包含在脚本中,因此人们偏爱
这对我有用。
我使用过重命名命令,以便任何文件的名称中都包含空格,那么mv命令不会在空格和实际文件之间造成混淆。
在这里,我将所有jpg文件的文件名中的空格'''替换为'_'
#!/ bin / bash 重命名'y / / _ /'* jpg#用_替换空格 令x = 0; 为* .jpg中的我做 令x =(x + 1) mv $ i $ x.jpg 完成
这是另一个使用“重命名”命令的解决方案:
find -name 'access.log.*.gz' | sort -Vr | rename 's/(\d+)/$1+1/ge'
rename 's/(\d+)/sprintf("%04d",$1)+1/ge'
Pero的回答把我带到了这里:)
我想重命名相对于时间的文件,因为图像查看器未按时间顺序显示图像。
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
blahblah; rm -r * blahblah.jpg
怎么办?只是一个极端的例子。
如果您使用图像注释器来标记图像。
$ make qt5py3
$ python3 labelImg.py