awk 解决方案

awk 解决方案

我有一个文件,其中包含许多连续和不连续的行,并且第一个单词相同,我想合并所有这些行。找不到任何方法。请给某人提出建议。

例如。

cat file
X blah blah blah
Y blah blah blah
X blah blah blah
z blah blah blah
X abc abc abc
z abc abc abc  

预期输出

X blah blah blah X blah blah blah X abc abc abc
Y blah blah blah
z abc abc abc z abc abc abc

我尝试
sed ':x; /^X/ { N; s/\n//; tx }' file 找到以 X 开头的行,并将它们的换行符连接起来,这样它们就可以连接起来了。但是没有用。

我是新手,了解不多。但我想要的是程序读取第一行,取出第一个单词,然后扫描所有其他行,看是否有与第一个单词相同的单词,如果遇到,则将第一行与该行合并,再次扫描第一行,查看文件中是否仍有任何行包含相同的第一个单词,如果没有,则读取第二行,然后进行同样的检查和合并过程。

通过这种方式,循环程序将继续扫描文件,直到不存在具有匹配的第一个单词的单行。

请注意,需要使用 sed 或 awk 或 perl 的一些语法才能实现上述功能。我不知道在其中使用高级循环和语法,所以在这里询问。

答案1

Perl 方式:

#!/usr/bin/perl 
use strict;
use warnings;
use feature 'say';
use Data::Dumper;

my $file = 'file.txt';
my %res;
open my $fh, '<', $file or die "unable to open '$file': $!";
# Read aech line of the file
while(<$fh>) {
    chomp;
    # split on space, 1 word and rest of the line
    my ($word, $line) = split/ /, $_, 2;
    # store the line in a hash with key = 1rst word
    $res{$word} .= '  ' . $_;
}
say Dumper \%res;

输出:

$VAR1 = {
          'Y' => '  Y blah blah blah',
          'X' => '  X blah blah blah  X blah blah blah  X abc abc abc',
          'z' => '  z blah blah blah  z abc abc abc  '
        };

答案2

awk 解决方案

使用 awk,命令如下:

awk -f CombineStrings.awk CombineStrings.txt

给出结果:

z blah blah blah z abc abc abc
X blah blah blah X blah blah blah X abc abc abc
Y blah blah blah

其中 CombineStrings.awk 包含:

{
  output[$1] = output[$1] " " $0
}

END {
  for ( line in output ) {
    sub( /^ /,"", line )
    print  output[ line ]
  }
}

相关内容