Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bash conditionnal getline with awk/tr/sed?

Tags:

bash

sed

awk

tr

I'm struggling with this, i want to concatenate a group of lines into a single one line/row. Each line (titi/toto/tata) of my file has 2 or 3 fields separated by a ";" So my input is like this:

titi1
titi2 
titi3
43;75;97
1;2;87
toto1
toto2
toto3
40;50;60
tata1
tata2
tata3
4;5;2
5;3;7
2;5;9

I need this output :

titi1;titi2;titi3;43;75;97
titi1;titi2;titi3;1;2;87
toto1;toto2;toto3;40;50;60
tata1;tata2;tata3;4;5;2
tata1;tata2;tata3;5;3;7
tata1;tata2;tata3;2;5;9

So has you can see the first 3 lines are informations (toto/tata etc...) that should be repeated for each line after that start with a number.

First my input had only one line with number so it was a grouping 4 by 4. so i searched in the forum had i found an example and did this with a getline like this :

awk '{getline b; getline c; getline d;printf("%s %s %s %s\n",$0,b,c,d)}'

But then i started to have 2 or even 3 lign with numbers... So i'm struggling doing a 'conditionnal' that understand that it should repeat the first 3 lign everytime it sees a lign starting with a numbers.

like image 340
O.Wolf Avatar asked Mar 06 '23 10:03

O.Wolf


2 Answers

Could you please try following.

awk '
{
  sub(/ +$/,"")
}
/^[a-zA-Z]+/{
  if(val && flag){
    val=""
  }
  val=val?val ";" $0:$0
  flag=""
  next
}
{
  flag=1
  print val ";" $0
}'  Input_file

Solution 2nd: In case your Input_file could have last line as tot etc and you want to print it too then use following.

awk '
{
  sub(/ +$/,"")
}
/^[a-zA-Z]+/{
  if(val && flag){
     val=""
  }
  val=val?val ";" $0:$0
  flag=""
  next
}
{
  flag=1
  print val ";" $0
}
END{
  if(val && !flag){
     print val
  }
}'  Input_file
like image 81
RavinderSingh13 Avatar answered Apr 27 '23 11:04

RavinderSingh13


$ awk -F';' 'NF>1{print s $0; p=1; next} p{s=p=""} {s=s $0 FS}' file
titi1;titi2;titi3;43;75;97
titi1;titi2;titi3;1;2;87
toto1;toto2;toto3;40;50;60
tata1;tata2;tata3;4;5;2
tata1;tata2;tata3;5;3;7
tata1;tata2;tata3;2;5;9

wrt your original script - see http://awk.freeshell.org/AllAboutGetline for why not to use getline for this (or most other situations) and how to call getline correctly on those rare occasions when it is appropriate to do so.

like image 24
Ed Morton Avatar answered Apr 27 '23 10:04

Ed Morton