在perl中按生成顺序写入文件名

在perl中按生成顺序写入文件名,perl,Perl,我在一个目录中有大约1000个文件。文件的命名约定如下所示 TC_01_abcd_16_07_2014_14_06.txt TC_02_abcd_16_07_2014_14_06.txt TC_03_abcd_16_07_2014_14_07.txt . . . . TC_100_abcd_16_07_2014_15_16.txt . . . TC_999_abcd_16_07_2014_17_06.txt 我已经写了一些这样的代码 my @dir="/var/tmp"; foreach my

我在一个目录中有大约1000个文件。文件的命名约定如下所示

TC_01_abcd_16_07_2014_14_06.txt
TC_02_abcd_16_07_2014_14_06.txt
TC_03_abcd_16_07_2014_14_07.txt
.
.
.
.
TC_100_abcd_16_07_2014_15_16.txt
.
.
.
TC_999_abcd_16_07_2014_17_06.txt
我已经写了一些这样的代码

my @dir="/var/tmp";
foreach my $inputfile (glob("$dir/*abcd*.txt")) {
print $inputfile."\n";
}
运行此命令时,它没有按顺序打印

它打印到09文件,然后它打印第1000个文件名

TC_01_abcd_16_07_2014_11_55.txt
TC_02_abcd_16_07_2014_11_55.txt
TC_03_abcd_16_07_2014_11_55.txt
TC_04_abcd_16_07_2014_11_55.txt
TC_05_abcd_16_07_2014_11_56.txt
TC_06_abcd_16_07_2014_11_56.txt
TC_07_abcd_16_07_2014_11_56.txt
TC_08_abcd_16_07_2014_11_56.txt
TC_09_abcd_16_07_2014_11_56.txt
TC_100_abcd_16_07_2014_12_04.txt
TC_101_abcd_16_07_2014_12_04.txt
TC_102_abcd_16_07_2014_12_04.txt
TC_103_abcd_16_07_2014_12_04.txt
TC_104_abcd_16_07_2014_12_04.txt
TC_105_abcd_16_07_2014_12_04.txt
TC_106_abcd_16_07_2014_12_04.txt
TC_107_abcd_16_07_2014_12_04.txt
TC_108_abcd_16_07_2014_12_05.txt
TC_109_abcd_16_07_2014_12_05.txt
TC_10_abcd_16_07_2014_11_56.txt
TC_110_abcd_16_07_2014_12_05.txt
TC_111_abcd_16_07_2014_12_05.txt
TC_112_abcd_16_07_2014_12_05.txt
TC_113_abcd_16_07_2014_12_05.txt
TC_114_abcd_16_07_2014_12_05.txt
TC_115_abcd_16_07_2014_12_05.txt
TC_116_abcd_16_07_2014_12_05.txt
TC_117_abcd_16_07_2014_12_05.txt
TC_118_abcd_16_07_2014_12_05.txt
TC_119_abcd_16_07_2014_12_06.txt
TC_11_abcd_16_07_2014_11_56.txt

请指导我如何按顺序打印

文件按照shell glob扩展的规则进行排序,这是一种简单的alpha排序。您需要根据第一个数字字段的数字排序对它们进行排序

有一种方法可以做到这一点:

# Declare a sort comparison sub, which extracts the part of the filename
# which we want to sort on and compares them numerically.
# This sub will be called by the sort function with the variables $a and $b
# set to the list items to be compared
sub compareFilenames {
        my ($na) = ($a =~ /TC_(\d+)/);
        my ($nb) = ($b =~ /TC_(\d+)/);
        return $na <=> $nb;
}

# Now use glob to get the list of filenames, but sort them
# using this comparison
foreach my $file (sort compareFilenames glob("$dir/*abcd*.txt")) {
        print "$file\n";
}
#声明一个排序比较子项,它提取文件名的一部分
#我们想对其进行排序并进行数字比较。
#sort函数将使用变量$a和$b调用此sub
#设置为要比较的列表项
子比较函数{
我的($na)=($a=~/TC_(\d+)/);
我的($nb)=($b=~/TC_u(\d+)/);
返回$na$nb;
}
#现在使用glob获取文件名列表,但对它们进行排序
#使用这个比较
foreach my$文件(排序compareFilenames全局(“$dir/*abcd*.txt”)){
打印“$file\n”;
}

请参阅:

按顺序打印文件--即ASCII顺序

在ASCII码中,排序时下划线(
\uu
)位于数字之后。如果你想按正确的顺序对文件排序,你必须自己排序。如果没有
排序
,则无法保证它们将以任何顺序打印。更糟糕的是,您实际上不希望以数字排序顺序(因为文件名不是数字)或ASCII顺序(因为您希望
TC\u 10
TC\u 100
之前打印)打印文件

因此,您需要编写自己的排序例程。Perl为您提供了该命令。默认情况下,它将按ASCII顺序排序。但是,您可以定义自己的子例程,以便按所需的顺序进行排序。
sort
将在排序例程
$a
$b
中向您传递两个值。您可以解析这两个值要获取所需的排序键,请使用
cmp
运算符以正确的排序顺序返回值:

#! /usr/bin/env perl
use warnings;
use strict;
use autodie;
use feature qw(say);

opendir my $dir, 'temp';      # Opens a directory for reading
my @dir_list = readdir $dir;
closedir $dir;

@dir_list = sort {   # My sort routine embedded inside the sort command
    my $a_val;
    my $b_val;
    if ( $a =~ /^TC_(\d+)_/ ) {
        $a_val = $1;
    }
    else {
        $a_val = 0;
    }
    if ( $b =~ /^TC_(\d+)_/ ) {
        $b_val = $1;
    }
    else {
        $b_val = 0;
    }
    return $a_val <=> $b_val;
} @dir_list;


for my $file (@dir_list) {
    next if $file =~ /^\./;
    say "$file";
}
文件按
TC\uu
之后的第一组数字进行数字排序

#!/usr/bin/perl
use warnings;
use strict;

sub by_substring{
   $a=~ /(\d+)/;
   my $x=$1;
   $b=~ /(\d+)/;
   my $y=$1;
   return $x <=> $y;
}

my @files=<*.txt>;
@files = sort by_substring @files;
for my $inputfile (@files){
   print $inputfile."\n";
}
!/usr/bin/perl
使用警告;
严格使用;
子串{
$a=~/(\d+)/;
my$x=$1;
$b=~/(\d+)/;
my$y=$1;
返回$x$y;
}
我的@files=;
@files=按子字符串@files排序;
对于我的$inputfile(@files){
打印$inputfile。“\n”;
}

无论您的文件名是否以“TC”、“BD”或“President Carter”开头,这都将只使用第一组相邻的数字进行排序。

目录中的排序将是字母数字,因此您的效果会更好。我不知道如何按创建日期对glob进行排序,这里有一个解决方法:

my @dir="/var/tmp";
my @files = glob("$dir/*abcd*.txt");
my @sorted_files;
for my $filename (@files) {
 my ($number) = $filename =~ m/TC_(\d+)_abcd/;
 $sorted_files[$number] = $filename;
}
print join "\n", @sorted_filenames;

你想要的顺序是第一个下划线和第二个下划线之间的数字吗?嗨,马克,我真的很喜欢你提供的解决方案。简单易用,谢谢大家。非常好!很高兴为您服务-请记住投票支持和/或接受其中一个答案。
my @dir="/var/tmp";
my @files = glob("$dir/*abcd*.txt");
my @sorted_files;
for my $filename (@files) {
 my ($number) = $filename =~ m/TC_(\d+)_abcd/;
 $sorted_files[$number] = $filename;
}
print join "\n", @sorted_filenames;