我有一个输入文件:
XYZ_001
XYZ_005
XYZ_010
ABC_001
ABC_010
我想将这些行分组为:
XYZ,XYZ_001,XYZ_005,XYZ_010
ABC,ABC_001,ABC_010
我尝试过排序文件并过滤掉最后四个字符,但我不知道如何将它们组合在一起。基本上,我需要将与正则表达式匹配的行组合在一起。我的输入文件已排序。
我的档案很大。我不能啜饮整个文件。
答案 0 :(得分:3)
使用perl one-liner
perl -0777 -pe 's/^([^_]+_).*\K\n(?=\1)/,/mg; s/^([^_]*)\K/,$1/mg;' file
如果slurping不是一个选项,那么这个更长的形式逻辑将起作用:
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
答案 1 :(得分:1)
这是一个单行代码:
perl -ne 'chomp;if (/^([a-zA-Z]+)_/) { $hash{$1} .= ",$_"; } } END { for (keys %hash ) { print $_ . $hash{$_} . "\n" } ' input.txt
input.txt中:
XYZ_001
XYZ_005
XYZ_010
ABC_001
ABC_010
输出:
ABC,ABC_001,ABC_010
XYZ,XYZ_001,XYZ_005,XYZ_010
答案 2 :(得分:0)
你可以试试这种东西,它将你的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,
答案 3 :(得分:0)
perl onliner:
perl -F"_" -ane 'chomp;$s{$F[0]}.=",$_";END{ for $i (keys %s){print $i.$s{$i}."\n";} }' FILE
我使用uniq hash
答案 4 :(得分:0)
以下是使用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