将文件夹中的文件重命名为顺序数字

我想将目录中的文件重命名为顺序数字。根据文件的创建日期。

例如sadf.jpg0001.jpgwrjr3.jpg0002.jpg等等,前导零的数量取决于文件的总数(如果不需要,不需要额外的零)。

317656 次浏览

尝试使用循环letprintf作为填充:

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标志可以防止自动覆盖现有文件,使用--可以防止mv解释带有破折号的文件名作为选项。

我喜欢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

要计数项目和构建命令,使用腼腆的人。不过,请注意主要的区别。默认情况下,find搜索当前目录及其子目录中的文件,因此,如果有必要,请确保仅限制在当前目录中的搜索(使用man find查看如何搜索)。

在OSX上使用Pero的解决方案需要一些修改。我使用:

find . -name '*.jpg' \
| awk 'BEGIN{ a=0 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' \
| bash

注意:反斜杠是用来换行的

edit 2015年7月20日: 结合@ klastopher的反馈来引用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

用“重命名”命令

rename -N 0001 -X 's/.*/$N/' *.jpg

rename -N 0001 's/.*/$N.jpg/' *.jpg

请注意 这里的重命名命令包括-n,它预览重命名。要真正执行重命名,请删除-n . exe

如果你的rename不支持-N,你可以这样做:

ls -1 --color=never -c | xargs rename -n 's/.*/our $i; sprintf("%04d.jpg", $i++)/e'

请注意 这里的重命名命令包括-n,它预览重命名。要真正执行重命名,请删除-n . exe

编辑要从给定的数字开始,你可以使用下面的代码(看起来有点难看),只需将123替换为你想要的数字:

ls -1 --color=never  -c | xargs rename -n 's/.*/our $i; if(!$i) { $i=123; } sprintf("%04d.jpg", $i++)/e'

这将按创建时间列出文件(首先列出最新文件,将-r添加到ls以反向排序),然后将此文件列表发送给重命名。Rename使用regex中的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.

再次使用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脚本。尽管已经有很多好的答案,我还是决定把它贴出来,因为我觉得它对别人有帮助。请随意改进它!

numerate

@Gnutt你想要的行为可以通过输入以下内容来实现:

./numerate.sh -d <path to directory> -o modtime -L 4 -b <startnumber> -r

如果选项-r被省略,则扩孔只会被模拟(应该有助于测试)。

选项L描述目标数字的长度(将被前导零填充) 也可以使用选项-p <prefix> -s <suffix>添加前缀/后缀。< / p >

如果有人想在文件编号之前按数字排序,只需删除-o modtime选项。

下面是另一个使用"rename"命令的解决方案:

find -name 'access.log.*.gz' | sort -Vr | rename 's/(\d+)/$1+1/ge'
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)

对于没有扩展名的文件,会显示警告“使用未初始化的值[…]”;你可以忽略它。

rename命令中删除-n以实际应用重命名。

这个答案的灵感来自于Luke在2014年4月的回答。它忽略了Gnutt的要求,即根据文件总数设置前导零的数量。

要给一个文件夹中的6000个文件重新编号,您可以使用ACDsee程序的“重命名”选项。

用于定义前缀的格式为:####"*"

然后设置起始号码,按重命名,程序将重命名所有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一行代码,它保留了原来的扩展名,增加了前导零,并且也适用于OSX:

num=0; for i in *; do mv "$i" "$(printf '%04d' $num).${i#*.}"; ((num++)); done

http://ubuntuforums.org/showthread.php?t=1355021的简化版本

按时间排序,限制为jpg,前导零和一个基底名(以防你可能想要一个):

ls -t *.jpg | cat -n |                                           \
while read n f; do mv "$f" "$(printf thumb_%04d.jpg $n)"; done

(都在一行上,没有\)

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

在OSX,从Homebrew安装重命名脚本:

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'

重命名vn -删除n关闭测试模式

{$ i = 1;} -控制开始编号

“% 04 d.jpg” -控制计数0 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是一种安全风险。但这不是我的情况,因为我使用我的扫描照片。

将所有文件重命名为序列和小写扩展名:

rename --counter-format 000001 --lower-case --keep-extension --expr='$_ = "$N" if @EXT' *

这是对我有效的方法 我已经使用了重命名命令,因此如果任何文件的名称中包含空格,那么mv命令不会混淆空格和实际文件

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

现在有一个选项后,你选择多个文件重命名(我已经看到在thunar文件管理器)。

  1. 选择多个文件
  2. 检查选项
  3. 选择重命名
提示符包含该特定目录下的所有文件 只需检查类别部分

我花了3-4个小时为一篇文章开发这个解决方案: https://www.cloudsavvyit.com/8254/how-to-bulk-rename-files-to-numeric-file-names-in-linux/ < / p >
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

这适用于任何类型的文件名(空格,特殊字符),通过使用正确的\0转义的findxargs,如果你愿意,你可以通过将echo 1增加到任何其他数字来设置开始文件命名偏移量。

在开始时设置扩展名(这里的示例为pdf)。它也不会覆盖任何现有文件。

find .  | grep 'avi' | nl -nrz -w3 -v1 | while read n f; do mv "$f" "$n.avi"; done

find .将显示文件夹和子文件夹中的所有文件。

grep 'avi'将过滤所有具有avi扩展名的文件。

nl -nrz -w3 -v1将显示从001 002开始的序列号,后面跟着文件名。

while read n f; do mv "$f" "$n.avi"; done将文件名更改为序列号。

使用sed:

ls -tr | sed "s/(.*)/mv '\1' \=printf('%04s',line('.').jpg)/" > rename.sh
bash rename.sh

通过这种方式,您可以在执行脚本之前检查脚本,以避免出现大错误

与创建日期无关,但根据已排序的名称编号:

python3 -c \
'ext="jpg"
start_num=0
pad=4
import os,glob
files=glob.glob(f"*.{ext}")
files.sort()
renames=list(zip(files,range(start_num,len(files)+start_num)))
for r in renames:
oname=r[0]
nname=f"{r[1]:0{pad}}.{ext}"
print(oname,"->",nname)
os.rename(oname,nname)
'