用Bash或Perl重命名和移动文件

Kat*_*tie 5 unix bash scripting perl

嗨,我对Bash和StackOverflow完全不熟悉.

我需要将一组文件(全部包含在同一文件夹中)移动到目标文件夹,其中可能已存在具有相同名称的文件.

如果存在特定文件,我需要在移动文件之前重命名该文件,方法是在文件名后附加一个增量整数.

应保留扩展名(换句话说,附加的增量整数应该扩展名之前).文件名可以包含中间的点.

最初,我正在考虑比较两个文件夹以获得现有文件的列表(我用"comm"做了这个),但后来我有点卡住了.我想我只是想以最复杂的方式做事.

有什么暗示以"bash方式"做到这一点?如果它是在bash脚本以外的脚本中完成的,那就没关系.

Ign*_*ams 7

如果您不介意重命名已存在的文件,GNU mv可以--backup选择:

mv --backup=numbered * /some/other/dir
Run Code Online (Sandbox Code Playgroud)


DVK*_*DVK 3

根据 OP,这可以是 Perl,而不仅仅是 bash。开始了

新解决方案:(注意扩展)

~/junk/a1$ ls
f1.txt   f2.txt   f3.txt   z1       z2


~/junk/a1$ ls ../a2
f1.txt     f2.1.txt   f2.2.txt   f2.3.txt   f2.txt     z1

# I split the one-liner into multiple lines for readability
$ perl5.8 -e 
     '{use strict; use warnings; use File::Copy; use File::Basename; 
       my @files = glob("*"); # assume current directory
       foreach my $file (@files) {
           my $file_base2 = basename($file); 
           my ($file_base, $ext) = ($file_base2 =~ /(.+?)([.][^.]+$)?$/);
           my $new_file_base = "../a2/$file_base";
           my $new_file = $new_file_base . $ext; 
           my $counter = 1;
           while (-e $new_file) { 
               $new_file = "$new_file_base." . $counter++ . $ext;
           }
           copy($file, $new_file)
               || die "could not copy $file to $new_file: $!\n";
        } }'

~/junk/a1> ls ../a2
f1.1.txt f1.txt  f2.1.txt  f2.2.txt  f2.3.txt  f2.4.txt  f2.txt  f3.txt
z1         z1.1       z2
Run Code Online (Sandbox Code Playgroud)

旧解决方案:(不注意扩展)

~/junk/a1$ ls
f1   f2   f3

~/junk/a1$ ls ../a2
f1     f2     f2.1   f2.2   f2.3

# I split the one-liner into multiple lines for readability
$ perl5.8 -e 
     '{use strict; use warnings; use File::Copy; use File::Basename; 
       my @files = glob("*"); # assume current directory
       foreach my $file (@files) {
           my $file_base = basename($file); 
           my $new_file_base = "../a2/$file_base"; 
           my $new_file = $new_file_base; 
           my $counter = 1;
           while (-e $new_file) { $new_file = "$new_file_base." . $counter++; }
           copy($file,$new_file)
               || die "could not copy $file to $new_file: $!\n";
        } }'

~/junk/a1> ls ../a2
f1     f1.1   f2     f2.1   f2.2   f2.3   f2.4   f3
Run Code Online (Sandbox Code Playgroud)