将文本文件中的行匹配在一起

时间:2014-06-26 20:56:28

标签: regex linux perl grep

我有一个输入文件:

XYZ_001
XYZ_005
XYZ_010
ABC_001
ABC_010

我想将这些行分组为:

XYZ,XYZ_001,XYZ_005,XYZ_010
ABC,ABC_001,ABC_010

我尝试过排序文件并过滤掉最后四个字符,但我不知道如何将它们组合在一起。基本上,我需要将与正则表达式匹配的行组合在一起。我的输入文件已排序。

我的档案很大。我不能啜饮整个文件。

5 个答案:

答案 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