Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 将文件夹中的文件重命名为序列号_Bash_Rename_Batch Rename - Fatal编程技术网

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

Bash 将文件夹中的文件重命名为序列号,bash,rename,batch-rename,Bash,Rename,Batch Rename,我想将目录中的文件重命名为序列号。基于文件的创建日期 例如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标志可以防止

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


例如
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
标志可以防止自动覆盖现有文件。

我喜欢gauteh的解决方案,因为它简单,但它有一个重要的缺点。在数千个文件上运行时,您可能会收到“argumentlist too long”消息(),其次,脚本可能会变得非常慢。在我的例子中,在大约36000个文件上运行它,脚本每秒移动大约一个项目!我不太清楚为什么会发生这种情况,但我从同事那里得到的规则是“
find
是你的朋友”


要计算项目和生成命令,请使用。不过,请注意主要区别。默认情况下,
find
搜索当前目录及其子目录中的文件,因此确保仅在必要时限制对当前目录的搜索(使用
manfind
查看如何进行)。

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

find . -name '*.jpg' \
| awk 'BEGIN{ a=0 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' \
| bash
注:反斜杠用于行延续

2015年7月20日编辑:
合并@klaustopher的反馈,引用
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
使用“重命名”命令


如果您的
重命名
不支持
-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'-FileName再次使用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脚本。我决定把它贴出来,不管有多少好的答案已经贴出来了,因为我认为它可以帮助别人。请随意改进它

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

./numerate.sh -d <path to directory> -o modtime -L 4 -b <startnumber> -r
/numerate.sh-d-o modtime-L 4-b-r
如果省略选项
-r
,则仅模拟铰孔(应有助于测试)

otion L描述目标编号的长度(将用前导零填充) 还可以使用选项
-p
-s
添加前缀/后缀


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

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


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

a.jpg
b.JPG
c.jpeg
d.tar.gz
e
然后,
ls-1cr
精确地输出上面的列表。然后可以使用
重命名

ls-1cr | xargs rename-n's/^[^\.]*(\..*)?$/我们的$i;sprintf(“%03d$1”,$i++)/e'
哪个输出

rename(a.jpg,000.jpg)
重命名(b.JPG,001.JPG)
重命名(c.jpeg,002.jpeg)
重命名(d.tar.gz,003.tar.gz)
在(eval 4)第1行的串联(.)或字符串中使用未初始化的值$1。
重命名(e,004)
对于没有扩展名的文件显示警告“使用未初始化值[…]”;你可以忽略它

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


这个答案的灵感来自于。它忽略了Gnutt根据文件总量设置前导零数的要求。

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

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


然后设置起始编号并按Rename,程序将使用序列号重命名所有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 one liner,它保留原始扩展名,添加前导零,并在OSX中工作:

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

简化版的

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


(全部在一行上,没有
\

佩罗的回答把我带到这里:)

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

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上安装自制的重命名脚本:

brew install rename
然后你就可以轻松地做到这一点:

rename -e 's/.*/$N.jpg/' *.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); 
}
ls -v | cat -n | while read n f; do mv -n "$f" "$n.ext"; done 
num=0; for i in *; do mv "$i" "$(printf '%04d' $num).${i#*.}"; ((num++)); done
ls -t *.jpg | cat -n |                                           \
while read n f; do mv "$f" "$(printf thumb_%04d.jpg $n)"; done
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
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'
ls -v | gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | bash
rename --counter-format 000001 --lower-case --keep-extension --expr='$_ = "$N" if @EXT' *
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
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
a=1
 # reset the variable if you 
 # want to use the script 2nd
 # time in the same directory

for i in *.jpg; do

 mv -- "$i" "walp_$a.jpg"

 a=`expr $a + 1`

done