287

我想将目录中的文件重命名为序号。基于文件的创建日期。

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

4

26 回答 26

379

尝试使用循环 ,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将带有破折号的文件名解释为选项。

于 2010-07-09T10:18:16.123 回答
366

美在一条线:

ls -v | cat -n | while read n f; do mv -n "$f" "$n.ext"; done 

您可以.ext使用.png,.jpg等进行更改。

于 2015-12-08T10:20:08.610 回答
64

我喜欢 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查看如何)。

于 2011-12-14T09:57:38.053 回答
37

一个非常简单的 bash one 衬里,它保留原始扩展,添加前导零,并且也适用于 OSX:

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

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

于 2016-06-15T05:17:49.117 回答
33

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

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

注意:反斜杠用于续行

2015 年 7 月 20 日编辑: 合并@klaustopher 的反馈以引用命令的\"%s\"参数,mv以支持带空格的文件名。

于 2012-05-28T06:29:59.740 回答
30

使用“重命名”命令

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

或者

rename -N 0001 's/.*/$N.jpg/' *.jpg
于 2014-02-04T15:45:12.283 回答
14

要在所有情况下工作,请将 \" 用于名称中包含空格的文件

find . -name '*.jpg' | gawk 'BEGIN{ a=1 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' | bash
于 2013-08-20T13:10:55.947 回答
11

如果您rename不支持-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 文档,在“重命名示例”下

   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.
于 2014-04-21T22:51:50.157 回答
10

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

brew install rename

然后你可以很容易地做到这一点:

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

或者添加一个不错的前缀:

rename -e 's/.*/photo-$N.jpg/' *.jpg
于 2017-07-07T18:07:41.860 回答
4

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

rename --counter-format 000001 --lower-case --keep-extension --expr='$_ = "$N" if @EXT' *
于 2018-10-24T08:50:11.173 回答
2
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 将文件名更改为序列号。

于 2021-09-03T18:21:11.550 回答
0

再次使用 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 
于 2014-06-07T11:24:06.037 回答
0

我有一个类似的问题并为此编写了一个 shell 脚本。尽管已经发布了许多好的答案,但我决定发布它,因为我认为它可能对某人有所帮助。随意改进它!

计算

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

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

如果-r省略该选项,则仅模拟铰孔(应该有助于测试)。

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

如果有人希望在编号之前对文件进行数字排序,只需删除该-o modtime选项即可。

于 2014-09-23T16:05:52.007 回答
0
a=1

for i in *.jpg; do
 mv -- "$i" "$a.jpg"
 a=`expr $a + 1`
done
于 2015-07-07T09:47:21.767 回答
0

假设我们在一个目录中有这些文件,按创建顺序列出,第一个是最旧的:

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 的要求,即根据文件总数设置前导零的数量。

于 2015-09-16T17:44:54.163 回答
0

大多数其他解决方案将覆盖已命名为数字的现有文件。如果运行脚本,添加更多文件,然后再次运行脚本,这尤其是一个问题。

此脚本首先重命名现有的数字文件:

#!/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); 
}
于 2015-11-23T12:53:39.983 回答
0

按时间排序,仅限于 jpg、前导零和基本名称(如果您可能想要一个):

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

(全部在一条线上,没有\

于 2016-11-02T01:26:08.727 回答
0

我花了 3-4 个小时为一篇关于此的文章开发此解决方案: https ://www.cloudsavvyit.com/8254/how-to-bulk-rename-files-to-numeric-file-names-in-linux/

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转义,如果您愿意,您可以通过增加任何其他数字来设置起始文件命名偏移量。findxargsecho 1

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

于 2020-11-28T03:48:11.190 回答
-1
ls -1tr | rename -vn 's/.*/our $i;if(!$i){$i=1;} sprintf("%04d.jpg", $i++)/e'

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

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

"%04d.jpg" - 控制计数为零04并设置输出扩展名.jpg

于 2018-03-17T22:40:47.673 回答
-1

对我来说,这种答案组合非常有效:

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 是一种安全风险。但这对我来说并非如此,因为我使用的是扫描的照片。

于 2018-05-28T09:37:41.917 回答
-1

这对我有用。
我使用了重命名命令,因此如果任何文件的名称中包含空格,那么mv命令不会在空格和实际文件之间混淆。

在这里,我将所有 jpg 文件的文件名中的空格 ' ' 替换为 '_'
#!/bin/bash
rename 'y/ /_/' *jpg #用_替换空格
让 x=0;
*.jpg 中的 i ;做
    让 x=(x+1)
    mv $i $x.jpg
完毕
于 2020-03-19T05:35:34.977 回答
-1

现在,在您选择多个文件进行重命名后,有一个选项(我在 thunar 文件管理器中看到过)。

  1. 选择多个文件
  2. 检查选项
  3. 选择重命名

该特定目录中的所有文件都会出现提示,只需检查类别部分

于 2020-05-01T08:27:19.417 回答
-2

此脚本将在 Mac OS bash 上按创建日期对文件进行排序。我用它来批量重命名视频。只需更改扩展名和名称的第一部分。

ls -trU *.mp4| awk 'BEGIN{ a=0 }{ printf "mv %s lecture_%03d.mp4\n", $0, a++ }' | bash
于 2013-04-12T06:02:35.670 回答
-2

这是使用“重命名”命令的另一个解决方案:

find -name 'access.log.*.gz' | sort -Vr | rename 's/(\d+)/$1+1/ge'
于 2014-11-07T16:27:30.147 回答
-3

佩罗的回答让我来到这里:)

我想相对于时间重命名文件,因为图像查看器没有按时间顺序显示图像。

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
于 2016-12-12T04:02:38.587 回答
-4

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

要定义前缀,请使用以下格式:####"*"

然后设置开始编号并按重命名,程序将用序号重命名所有 6000 个文件。

于 2015-11-09T17:00:39.747 回答