我正在尝试找到这种模式匹配。我想匹配并仅显示同一行中的第一个匹配项。其中一个匹配,第四个字段可以匹配两个模式中的任何一个,即; A,BCD.EF或AB.CD。一个例子是
Example 1:
12:23 23:23 ASDFGH 1,232.00 22.00
21:22 12:12 ASDSDS 22.00 21.00
预期输出为
Expected Result 1:
12:23 ASDFGH 1,232.00
21:22 ASDSDS 22.00
使用我对grep和stackoverflow的一点知识,我已经做到了这一点。
< test_data.txt grep -one "[0-9]/[0-9][0-9]\|[0-9]*,[0-9]*.[0-9][0-9]\|[0-9]*.[0-9][0-9]" | awk -F ":" '$1 == y { sub(/[^:]:/,""); r = (r ? r OFS : "") $0; next } x { print x, r; r="" } { x=$0; y=$1; sub(/[^:]:/,"",x) } END { print x, r }'
任何使这更简单或更清洁并实现完整功能的想法。
更新1:其他几个例子可能是:
Example 2:
12:21 11111 11:11 ASADSS 11.00 11.00
22:22 111232 22:22 BASDASD 1111 1,231.00 1,121.00
更新2:似乎某种程度上我的问题不明确。因此,查看它的一种方法是查找:我在一行上找到的第一个“时间”,第一组字母数字字符串和第一个带/不带逗号的十进制值,所有这些都打印在同一输出上线。更一般的描述是,给定输入行,在输出中的一行中打印模式1的第一次出现,模式2的第一次出现和模式3的第一次出现(其本身是“或”两种模式)必须是稳定的(即;保持它们在输入中出现的顺序)。对不起,这是一个有点复杂的例子,我也试图了解这是否是使用Unix实用程序为Perl / Python等完整语言留下的最佳位置。所以这是第二组例子的预期结果。
Expected Result 2:
12:21 ASADSS 11.00
22:22 BASDASD 1,231.00
答案 0 :(得分:3)
#!/usr/bin/awk -f
BEGIN {
p[0] = "^[0-9]+:[0-9]{2}$"
p[1] = "^[[:alpha:]][[:alnum:]]*$"
p[2] = "^[0-9]+[0-9,]*[.][0-9]{2}$"
}
{
i = 0
for (j = 1; j <= NF; ++j) {
for (k = 0; k in p; ++k) {
if ($j ~ p[k] && !q[k]++ && j > ++i) {
$i = $j
}
}
}
q[0] = q[1] = q[2] = 0
NF = i
print
}
输入:
12:23 23:23 ASDFGH 1,232.00 22.00
21:22 12:12 ASDSDS 22.00 21.00
12:21 11111 11:11 ASADSS 11.00 11.00
22:22 111232 22:22 BASDASD 1111 1,231.00 1,121.00
输出:
12:23 ASDFGH 1,232.00
21:22 ASDSDS 22.00
12:21 ASADSS 11.00
22:22 BASDASD 1,231.00
答案 1 :(得分:1)
Perl-regex风格应解决问题:
(\d\d:\d\d).*?([a-zA-Z]+).*?((?:\d,\d{3}\.\d\d)|(?:\d\d\.\d\d))
它将捕获以下数据(处理您单独提供的每一行):
RESULT$VAR1 = [
'12:23',
'ASDFGH',
'1,232.00'
];
RESULT$VAR1 = [
'21:22',
'ASDSDS',
'22.00'
];
RESULT$VAR1 = [
'12:21',
'ASADSS',
'11.00'
];
RESULT$VAR1 = [
'22:22',
'BASDASD',
'1,231.00'
];
示例perl script.pl:
#!/usr/bin/perl
use strict;
use Data::Dumper;
open my $F, '<', shift @ARGV;
my @strings = <$F>;
my $qr = qr/(\d\d:\d\d).*?([a-zA-Z]+).*?((?:\d,\d{3}\.\d\d)|(?:\d\d\.\d\d))/;
foreach my $string (@strings) {
chomp $string;
next if not $string;
my @tab = $string =~ $qr;
print join(" ", @tab) . "\n";
}
运行方式:
perl script.pl test_data.txt
干杯!