我想将目录中的文件重命名为序列号。基于文件的创建日期。
例如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
标志可防止自动覆盖现有文件。
你也可以使用ls
ls *.JPG| awk 'BEGIN{ a=0 }{ printf "mv %s gopro_%04d.jpg\n", $0, a++ }' | bash
我有一个类似的问题,并为此编写了一个shell脚本。我决定发布它,无论已经发布了许多好的答案,因为我觉得它对某人有帮助。随意改进它!
@Gnutt您可以通过键入以下内容来实现您想要的行为:
./numerate.sh -d <path to directory> -o modtime -L 4 -b <startnumber> -r
如果省略选项-r
,则仅模拟扩孔(应该有助于测试)。
运动L描述目标数量的长度(将用前导零填充)也可以使用选项-p <prefix>
-s <suffix>
添加前缀/后缀。
如果有人想要在编号之前对文件进行数字排序,只需删除-o modtime
选项即可。
a=1
for i in *.jpg; do
mv -- "$i" "$a.jpg"
a=`expr $a + 1`
done
我们假设我们将这些文件放在一个目录中,按创建顺序列出,第一个是最早的:
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’s answer of April 2014。它忽略了Gnutt根据文件总量设置前导零数的要求。
再次使用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
ls -1tr | rename -vn 's/.*/our $i;if(!$i){$i=1;} sprintf("%04d.jpg", $i++)/e'
rename -vn - 删除n关闭测试模式
{$ i = 1;} - 控制起始编号
“%04d.jpg” - 控制计数零04并设置输出扩展名.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是一种安全风险。但是当我使用扫描的照片时,情况并非如此。
大多数其他解决方案将覆盖已命名为数字的现有文件。如果运行脚本,添加更多文件,然后再次运行脚本,则尤其会出现问题。
此脚本首先重命名现有的数字文件:
#!/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);
}
按时间排序,限制为jpg,前导零和基本名称(如果您可能需要一个):
ls -t *.jpg | cat -n | \
while read n f; do mv "$f" "$(printf thumb_%04d.jpg $n)"; done
(全部在一条线上,没有\
)
此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 -v | cat -n | while read n f; do mv -n "$f" "$n.ext"; done
你可以用.ext
,.png
等改变.jpg
。
按照命令将所有文件重命名为序列和小写扩展名:
rename --counter-format 000001 --lower-case --keep-extension --expr='$_ = "$N" if @EXT' *
如果您使用图像注释器标记图像。
$ make qt5py3
$ python3 labelImg.py
此脚本将在Mac OS bash上按创建日期对文件进行排序。我用它来批量重命名视频。只需更改扩展名和名称的第一部分即可。
ls -trU *.mp4| awk 'BEGIN{ a=0 }{ printf "mv %s lecture_%03d.mp4\n", $0, a++ }' | bash
这是另一个带有“rename”命令的解决方案:
find -name 'access.log.*.gz' | sort -Vr | rename 's/(\d+)/$1+1/ge'
佩罗的回答让我在这里:)
我想相对于时间重命名文件,因为图像查看器没有按时间顺序显示图像。
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
要重新编号6000,文件在一个文件夹中,您可以使用ACDsee程序的“重命名”选项。
要定义前缀,请使用以下格式:####"*"
然后设置起始编号并按重命名,程序将使用顺序编号重命名所有6000个文件。
我喜欢gauteh的简洁解决方案,但它有一个重要的缺点。当在数千个文件上运行时,你可以获得“参数列表太长”的消息(more on this),其次,脚本可能变得非常慢。就我而言,在大约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
查看方法)。
在OSX上使用Pero的解决方案需要进行一些修改。我用了:
find . -name '*.jpg' \
| awk 'BEGIN{ a=0 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' \
| bash
注意:反斜杠用于续行
编辑2015年7月20日:纳入@klaustopher的反馈,引用\"%s\"
命令的mv
参数,以支持带空格的文件名。
使用“重命名”命令
rename -N 0001 -X 's/.*/$N/' *.jpg
要么
rename -N 0001 's/.*/$N.jpg/' *.jpg
一个非常简单的bash one liner,它保留了原始扩展,添加了前导零,并且还在OSX中工作:
num=0; for i in *; do mv "$i" "$(printf '%04d' $num).${i#*.}"; ((num++)); done
要在所有情况下工作,请为名称中包含空格的文件添加\“
find . -name '*.jpg' | gawk 'BEGIN{ a=1 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' | bash
如果你的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 documentation,在“重命名示例”下
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.
在OSX上,从Homebrew安装重命名脚本:
brew install rename
然后你可以轻松地做到非常荒谬:
rename -e 's/.*/$N.jpg/' *.jpg
或者添加一个漂亮的前缀:
rename -e 's/.*/photo-$N.jpg/' *.jpg