将文件夹中的文件重命名为序列号

Gnu*_*utt 205 bash rename batch-rename

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

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

gau*_*teh 289

尝试使用循环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
Run Code Online (Sandbox Code Playgroud)

使用该-i标志可防止自动覆盖现有文件.

  • 您也可以执行`printf -v new"%04d.jpg"$ {a}`将值放入变量中.并且`((a ++))`用于递增变量.此外,这不会在创建日期顺序中执行,也不会最小化OP指定的填充.但是,应该注意Linux/Unix不存储创建日期. (4认同)
  • 需要双引号包装mv才能在我的bash环境中工作.mv"$ {i}""$ {new}" (3认同)
  • 我一眼就丢失了大约 800 个文件。我认为`-i`应该包含在答案中,并且应该相应地重写注释。那会更安全。:( (3认同)
  • 可能只是Cygwin(尽管它的终端行为与普通的Unix shell大致相同)但是当文件名中有空格时它似乎有问题. (2认同)
  • 可能还需要使用`mv - "$ i""$ new"来正确处理以破折号开头的源文件名; 实际上,`mv`会尝试将这些文件名解析为标志集合. (2认同)

小智 222

美丽在一条线上

ls -v | cat -n | while read n f; do mv -n "$f" "$n.ext"; done 
Run Code Online (Sandbox Code Playgroud)

用所需的.png,.jpg或其他方式更改.ext.

  • 像这样添加printf:`ls | 猫-n | 读取nf; 做mv"$ f"\`printf"%04d.extension"$ n \`; 完成`以零填充数字 (24认同)
  • 从对这个答案和其他人的评论中总结出一些好主意:`ls -1prt | grep -v "/$" | 猫 -n | 在阅读 nf 时;do mv -n "${f}" "$(printf "%04d" $n).${f#*.}"; done` **结果:** (1) 按修改顺序排序,后面的文件有后面的索引;(2) 忽略目录 - 而不是递归的;(3) 衬垫索引;(4)保持原有扩展。 (6认同)
  • 警告:您可能希望将"-n"添加到mv命令以防止意外覆盖文件.发现这很难! (5认同)
  • 传说:),我在windows上的git shell上使用了这个,效果很好!^^. (4认同)
  • 效果很好.美丽在一条线上.我添加了ls -tr按上次修改时间获取文件. (4认同)
  • @Lorenzo用`find替换`ls`.-type f`将仅列出当前目录中的文件 (2认同)
  • [为什么你不应该解析ls的输出](http://mywiki.wooledge.org/ParsingLs),使用`find`并正确过滤你的文件. (2认同)

Per*_*ero 60

我喜欢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
Run Code Online (Sandbox Code Playgroud)

为了计算项目和构建命令,使用了gawk.但请注意主要区别.默认情况下,find搜索当前目录及其子目录中的文件,因此请确保仅在必要时限制对当前目录的搜索(用于man find查看方式).

  • 这里存在巨大的安全漏洞.想想你是否有一个名为`$(rm -rf /).jpg`的文件. (12认同)
  • 我修改为使用行号`NR`来缩短命令.`gawk'{printf"mv%s%04d.jpg \n",$ 0,NR}'` (7认同)
  • 如果文件名有空格,则分解.在源文件名周围使用引号.printf"mv \"%s \"%04d.jpg \n",$ 0,a ++ (2认同)
  • @Pero你使用“mv”是危险的。除了 @CharlesDuffy 的反对之外,例如,如果(在运行脚本之前)已经有一个名为“0001.jpg”的文件,会发生什么?它将被处理的第一个文件默默地覆盖。其次,如果文件恰好以破折号开头,则“mv”会将文件名的其余部分视为标志。这两个问题都在 gauteh 的答案的评论中提到,以及它们的解决方案:使用 `mv -i --` 而不是 `mv`。除此之外,我同意使用“find”比使用 shell glob 更好,正如您所指出的原因。 (2认同)

bei*_*ei2 28

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

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

注意:反斜杠用于续行

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

  • 与Pero的解决方案一样,这里存在安全漏洞.想想你是否有一个名为`$(rm -rf /).jpg`的文件. (3认同)

Rom*_*rov 26

使用"重命名"命令

rename -N 0001 -X 's/.*/$N/' *.jpg
Run Code Online (Sandbox Code Playgroud)

要么

rename -N 0001 's/.*/$N.jpg/' *.jpg
Run Code Online (Sandbox Code Playgroud)

  • 我的`rename`(Linux Mint 13)没有`-N`选项. (30认同)
  • 我很想知道哪里有一个带有-N选项的重命名命令.我的Ubuntu 14.04没有它. (8认同)
  • 有[至少三种不同的工具,称为“重命名”](https://unix.stackexchange.com/q/229230/187122)。@Bostrot 发布的链接是另一种重命名工具,@RomanRhrnNesterov 似乎使用了该工具。¶ 致 Peder Stray 和 Larry Wall 的 `rename` 的所有用户(arch linux 上的包 `perl-rename` 和 debian/ubuntu 上的包 `rename`):您可以自己定义 `$N`:`perl-rename ' $N=sprintf("%04d",++$N); s/.*/$N.jpg/' *.jpg` (5认同)
  • [链接](http://plasmasturm.org/code/rename/)到带有计数器的版本。 (2认同)

Roy*_*rot 26

一个非常简单的bash one liner,它保留了原始扩展,添加了前导零,并且还在OSX中工作:

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

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

  • 请注意,这不会保留文件的原始* order *。 (2认同)

Abd*_*ira 11

要在所有情况下工作,请为名称中包含空格的文件添加\"

find . -name '*.jpg' | gawk 'BEGIN{ a=1 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' | bash
Run Code Online (Sandbox Code Playgroud)

  • 实际上并不涵盖所有情况.包含文字引号的文件名可以轻易地转义 - 因为你使用的是双引号而不是单引号,所以像`$(rm -rf /)`这样的扩展仍然很有用. (3认同)

Luk*_*e H 9

如果您rename不支持-N,可以执行以下操作:

ls -1 -c | xargs rename -n 's/.*/our $i; sprintf("%04d.jpg", $i++)/e'
Run Code Online (Sandbox Code Playgroud)

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

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

这将按创建时间顺序列出文件(最新的第一个,添加-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.
Run Code Online (Sandbox Code Playgroud)


小智 7

find .  | grep 'avi' | nl -nrz -w3 -v1 | while read n f; do mv "$f" "$n.avi"; done
Run Code Online (Sandbox Code Playgroud)

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

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

nl -nrz -w3 -v1将显示以 001 002 等开头的序列号,后跟文件名。

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


tri*_*web 6

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

brew install rename
Run Code Online (Sandbox Code Playgroud)

然后你可以轻松地做到非常荒谬:

rename -e 's/.*/$N.jpg/' *.jpg
Run Code Online (Sandbox Code Playgroud)

或者添加一个漂亮的前缀:

rename -e 's/.*/photo-$N.jpg/' *.jpg
Run Code Online (Sandbox Code Playgroud)

  • 那是一个很棒的脚本,它仅取决于Perl。brew仅适用于macs,但您可以从github(https://github.com/ap/rename)上获取它,并在Linux或Windows上使用它。 (2认同)
  • 这对我不起作用.我得到了'全局符号'$ N"需要显式包名(你忘了申报"我的$ N"吗?)(用户提供的代码). (2认同)