2

I have a file that contain many lines consecutive and non consecutive with same first word and i want to merge all those lines.Not finding any way. please suggest someone.

eg.

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  

Expected Output

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

I tried
sed ':x; /^X/ { N; s/\n//; tx }' file To find lines starting with X and to join their newline character so that they may join. But it did not worked.

I am newbie and I dont know much. But what I want is that program will read first line takes its first word and scan all other lines for having same word as first word and if it encounters then it will join 1st line with that line again scan 1st line and find for whether still any line in file contain same first word and if not then it will read second line and then same process of checking and merging.

In this way program in loop will keep scanning file until no single line with matching first words exist.

Please some syntax of sed or awk or perl is needed to achive above.I am not aware of using advance loops and syntaxes in them so i am asking here.

3
  • a few points. You wrote your question very well I can see you are very logical. A)at one point you said "similar" but you mean "same" 'cos you are a logical guy I can see that. Other times you got it right and said "same". B) sed operates line by line, at best it might be tricky.. C) perl can be used 'cos it's a proper programming language.. perl also famously has regexes but what you are looking for isn't really a regex thing. D)Other scripting languages could do it eg ruby. E)Basic programming is actually easier than trying to use Sed beyond sed's basic use cases.
    – barlop
    Jul 6, 2020 at 14:40
  • So I do recommend just learning programming. A loop is often not like a one liner, it's not that hard. There was once a language called qbasic and you could write DO PRINT "abc" LOOP. And that was it, that's a loop. You can add a counter or variable to it e.g. i=0 DO PRINT i LOOP. (and add an i=i+1 to the body!). Learn loops! Learn how to read a file. Learn arrays. Learn that basic programming.
    – barlop
    Jul 6, 2020 at 14:42
  • 1
    Err your profile says "Programmer, Developer" so maybe you know loops but just not in perl,, that's very odd. Just learn loops in perl then. And if you don't know how to do a loop in any programming language then you are not a programmer(yet).
    – barlop
    Jul 6, 2020 at 14:44

2 Answers 2

1

A Perl way:

#!/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;

Output:

$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  '
        };
0

An awk solution

Using awk, with this command:

awk -f CombineStrings.awk CombineStrings.txt

gives this result:

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

where CombineStrings.awk contains:

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

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .