我在目录中有大约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
请指导我如何按顺序打印
答案 0 :(得分:1)
根据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";
}
请参阅:perldoc for sort
答案 1 :(得分:0)
按顺序打印文件 - ASCII顺序。
在ASCII中,下划线(_
)位于排序后的数字之后。如果要按正确顺序对文件进行排序,则必须自行对其进行排序。如果没有sort
,则无法保证他们可以按任何顺序打印。对你来说更糟糕的是,你真的不想以数字排序顺序打印文件(因为文件名不是数字)或ASCII顺序(因为你希望在TC_10
之前打印TC_100
{1}}。
因此,您需要编写自己的排序例程。 Perl为您提供sort命令。默认情况下,它将按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";
}
在我的sort
子例程中,我将采用$a
和$b
并提取您想要对其进行排序的数字,并将该值放入$a_val
和{{ 1}}。如果文件没有我认为可能具有的名称,我还必须注意会发生什么。在这里,我只是决定将排序值设置为$b_val
并希望最好。
我正在使用0
和opendir
而非使用globbing。这最终会在我的列表中包含readdir
和.
,并且它将包含以..
开头的所有文件。没问题,我打印清单时会删除这些。
在我的测试中,打印出来:
.
文件按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_10_abcd_16_07_2014_11_56.txt
TC_11_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_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
之后的第一组数字进行数字排序。
答案 2 :(得分:0)
你走了:
#!/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";
}
如果您的文件名以“TC”或“BD”或“President Carter”开头,这将无关紧要,这只会使用第一组相邻数字进行排序。
答案 3 :(得分:0)
目录中的排序将是字母数字,因此您的效果。我不知道如何按创建日期对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;