Anand Abhay
Anand Abhay

Reputation: 359

Format Data using sed or awk

I am having data in below format in a file

Section : A1234,
Name : ABCBDEDF,
Medium : English ,
Age : No,   
Name : Reporting,
Age : No
Section : XYSZA,
Name : Work,
Age : YES   

I am trying to achieve data in below format :--

Section : A1234,Name : ABCBDEDF,Age : No
Section : A1234,Name : Reporting,Age : No
Section : XYSZA,Name : Work,Age : YES

I tried few sed and awk statements to but I am able to merge only all rows together.

awk '{key=$0; getline; print key "" $0;}' test.txt

Any help is appreciated.

Upvotes: 0

Views: 87

Answers (4)

sjsam
sjsam

Reputation: 21965

I have tried something with your modified input. Check if below works

awk '/^Section/{s=$0}
     /^Name/ && match(p,/^Age/){$0=sprintf("%s%s%s",s,ORS,$0)}
     {print;p=$0}' file_name | sed ':a;/Age/!{N;s/\n//g;ba}'

Output(Вывод)

Section : A1234,Name : ABCBDEDF,Medium : English ,Age : No,   
Section : A1234,Name : Reporting,Age : No
Section : XYSZA,Name : Work,Age : YES 

Note(Заметка) : The awk part does the preprocessing here to add Section in missing places and sed prints the output in required format.

Upvotes: 1

RavinderSingh13
RavinderSingh13

Reputation: 133770

Following awk may help you in same.

awk '/Section/{val1=$0;next} /Name/{val2=$0;next} /Age/{sub(/,/,"");print val1 val2 $0;}'   Input_file

EDIT: Since OP told OP requires everything between Section and flag strings then following may help in same.

awk '/Age/ && flag{sub(/,/,"");print val1  $0;val1=flag="";next} /Section/{val1=$0;flag=1;next} flag{val1=val1  $0;}'  Input_file

If you want to have everything between strings section and flag and we have to make sure each group should have section in it else it will NOT print it.

Upvotes: 1

paxdiablo
paxdiablo

Reputation: 882756

Based on what I consider the most likely input format, a section can have multiple name/age pairs following it.

If that's the case then you just need to store the last section seen, and output it with the name and age.

We can just store the most recently seen section and name and use that along with each age. That will also allow you to skip names in the input file but, if they're there, it will not have an effect.

That means that this should do the trick:

awk  '/^Section/{sec=$0}/^Name/{nm=$0}/^Age/{print sec""nm""$0}'

The following transcript shows it in action:

printf 'Section : A1234,\nName : ABCBDEDF,\nAge : No,\nName : Reporting,\nAge : No\nSection : XYSZA,\nName : Work,\nAge : YES\n' | awk  '/^Section/{sec=$0}/^Name/{nm=$0}/^Age/{print sec""nm""$0}'

with the output being, as you requested:

Section : A1234,Name : ABCBDEDF,Age : No,
Section : A1234,Name : Reporting,Age : No
Section : XYSZA,Name : Work,Age : YES

Note that the first line has a comma at the end, this is caused by that being in your input data. If you want it stripped out, that will add another minor complication to the code. For now, I'll just assume either your input data is incorrect or you want it echoed as-is.

Upvotes: 1

Cyrus
Cyrus

Reputation: 89009

With bash:

while IFS=" ," read -r x foo y; do 
  [[ $x == "Section" ]] && s="$y"
  [[ $x == "Name" ]] && n="$y"
  [[ $x == "Age" ]] && a="$y" && echo "Section : $s,Name : $n,Age : $a"
done < file

Output:

Section : A1234,Name : ABCBDEDF,Age : No
Section : A1234,Name : Reporting,Age : No
Section : XYSZA,Name : Work,Age : YES

Upvotes: 1

Related Questions