所以我有一个perl模块,它使用bash命令来获取带有某些" table"的文件。名。在我的具体情况下,它正在寻找名称为" event"的表格,但我也需要这个来处理所有名称。
目前,我在perl脚本中有以下代码来获取带有名称表的MYI文件,我不仅收到event_*
,还收到event_extra_data_*
。对于我的例子,我只需要在我的数据库中存在event_的第二个表。作为我的测试信息,我目前已经
event_1459161160_0
event_1459182760_0
event_extra_data_1459182745_0
event_extra_data_1459182760_0
是表格中的分区表格" event"和event_extra_data这是$table
变量在下面看到的值。
无论如何,我的问题是,我如何将此限制为只接收目前正在接收的event_1459182760_0.MYI
而不是event_extra_data_1459182760_0.MYI
?
elsif ($sql =~ /\{LAST\}/i )
{
$cmd = 'ls -1 /var/lib/mysql/sfsnort/'.$table.'_*MYI | grep -v template | tail -n1 | cut -d"/" -f6 | cut -d"." -f1';
$value = `$cmd`;
print "Search Value: $value\n";
if ($value eq "")
{
$sql = ""; # same as with FIRST
}
else
{
$sql =~ s/\{LAST\}/$value/g;
}
}
答案 0 :(得分:3)
不要解析ls
- 没有意义,而且很容易造成问题。
我会指出这一点 - perl中的glob
函数允许您对有限数量的“正则表达式”模式执行操作。 (注意 - 他们不是正则表达式,所以不要混淆它们。)
foreach my $filename ( glob "event_[0-9]*" ) {
#do something with $filename
}
如果你刚好在最后一次之后 - 按数字排序:
my ( $last ) = reverse sort glob "event_[0-9]*";
鉴于您有一条路径,那么您应该能够:
my ( $last ) = reverse sort glob "/var/lib/mysql/sfsnort/event_[0-9]*.MYI";
注意 - 假设您正在使用time()
数值,这是有效的 - 它正在进行字母数字排序(以及目录名称)。
如果这不是一个有效的假设,你需要一个自定义排序 - 这很简单,你可以对一个子程序进行排序以进行排序。
或者:
sort { my ($a1) = $a =~ /(\d+)/; my ($b1) = $b =~ /(\d+)/; $b1 <=> $a1 }
从路径中提取第一个“数字字符串”。 (注意 - 还包括目录)。
或使用-M
file test:
sort { -M $a <=> -M $b }
从文件中读取修改时间(技术上-M
是以天为单位的年龄)。
如果您进行自定义排序,则可以删除reverse
,只需交换$a
和$b
即可。
答案 1 :(得分:0)
虽然我认为在perl中做得更好,但要回答关于如何获取event_*
而不是event_extra*
的具体问题,您当然可以将其添加到grep
过滤掉,或者你可以使用不同的glob,如$table_[0-9]*
,如果总是有_
,那么表名后面会有一个数字。
在perl中你可以做类似下面的事情:
opendir( DIR, '/var/lib/mysql/sfsnort/' );
my @files = sort grep { /$table_\d/ } readdir( DIR );
closedir( DIR );
$files[$#files] =~ /(^[^.]+)/;
my $value = $1;