【发布时间】:2014-06-27 13:16:03
【问题描述】:
我有一个输入文件:
XYZ_001
XYZ_005
XYZ_010
ABC_001
ABC_010
我想将这些行分组为:
XYZ,XYZ_001,XYZ_005,XYZ_010
ABC,ABC_001,ABC_010
我已尝试对文件进行排序并过滤掉最后四个字符,但我不知道如何将它们组合在一起。基本上,我需要将匹配正则表达式的行组合在一起。我的输入文件已排序。
我的文件很大。我不能吞下整个文件。
【问题讨论】:
我有一个输入文件:
XYZ_001
XYZ_005
XYZ_010
ABC_001
ABC_010
我想将这些行分组为:
XYZ,XYZ_001,XYZ_005,XYZ_010
ABC,ABC_001,ABC_010
我已尝试对文件进行排序并过滤掉最后四个字符,但我不知道如何将它们组合在一起。基本上,我需要将匹配正则表达式的行组合在一起。我的输入文件已排序。
我的文件很大。我不能吞下整个文件。
【问题讨论】:
使用 perl 单行代码
perl -0777 -pe 's/^([^_]+_).*\K\n(?=\1)/,/mg; s/^([^_]*)\K/,$1/mg;' file
如果啜饮不是一种选择,那么这种较长形式的逻辑将起作用:
perl -ne '
chomp;
($h) = /([^_]*)/;
if ($l ne $h) {print "\n" if defined $l; $l = $h; print "$l"}
print ",$_";
}{
print "\n"
' file
开关:
-0777:啜饮整个文件-p:为输入文件中的每个“行”创建一个 while(<>){...; print} 循环。 -e:告诉perl 在命令行上执行代码。 代码:
s/^([^_]+_).*\K\n(?=\1)/,/mg:分组相关邻线:XYZ_001,XYZ_005,XYZ_010
s/^([^_]*)\K/,$1/mg:添加组前缀:XYZ,XYZ_001,XYZ_005,XYZ_010
【讨论】:
这是一个单一的班轮:
perl -ne 'chomp;if (/^([a-zA-Z]+)_/) { $hash{$1} .= ",$_"; } } END { for (keys %hash ) { print $_ . $hash{$_} . "\n" } ' input.txt
输入.txt:
XYZ_001
XYZ_005
XYZ_010
ABC_001
ABC_010
输出:
ABC,ABC_001,ABC_010
XYZ,XYZ_001,XYZ_005,XYZ_010
【讨论】:
您可以尝试这种方法,它将您的 id 和值存储在数组哈希中,然后遍历它们并打印:
use warnings;
use strict;
open my $in, '<', 'in.txt';
my %data;
my (@group, @n);
while (<$in>){
chomp;
my @split = split(/_/);
push @group, $split[0];
push @n, $split[1];
}
push @{$data{$group[$_]} }, [ $n[$_] ] for 0 .. $#group;
for my $group (reverse sort keys %data){
for my $vals (@ {$data{$group} }) {
my ($number) = @$vals;
print "$group\_$number,";
}
print "\n";
}
XYZ_001,XYZ_005,XYZ_010,
ABC_001,ABC_010,
【讨论】:
perl 在线:
perl -F"_" -ane 'chomp;$s{$F[0]}.=",$_";END{ for $i (keys %s){print $i.$s{$i}."\n";} }' FILE
我使用 uniq 哈希
【讨论】:
这是我使用awk 的方法
awk -F_ '{a[$1]=(a[$1]?a[$1]","$0:$0)} END {for (i in a) print i","a[i]}' file
ABC,ABC_001,ABC_010
XYZ,XYZ_001,XYZ_005,XYZ_010
【讨论】: