Roger
Roger

Reputation: 95

convert multiple lines into single line in a file only after a specific pattern

I am trying to convert multiple lines into single line only after a specific pattern, in a text file on Solaris 10 machine.

file be like:-

<open>
   <bas>ABC1</bas>
   <stat>1</stat>
</open>
<open>
   <bas>ABC10</bas>
   <stat>1</stat>
</open>
<open>
   <bas>ABC11</bas>
   <stat>4</stat>
   <line>1234</line>
</open>
<new>
</new>

expected output:-

<open><bas>ABC1</bas><stat>1</stat></open>
<open><bas>ABC10</bas><stat>1</stat></open>
<open><bas>ABC11</bas><stat>4</stat><line>1234</line></open>
<new>
</new>

I tried with but didn't succeed

perl -pne 'chomp unless(/^<\/open>/);' file_name

Upvotes: -1

Views: 101

Answers (2)

ufopilot
ufopilot

Reputation: 3985

GNU AWK

awk '
    /<open>/,/<\/open>/{
        out=out gensub(/^ *(.*)/,"\\1",1); 
        if(match($0,/^<\/open>/)){
            print out
            out=""
        }
        next
    }1
' file

<open><bas>ABC1</bas><stat>1</stat></open>
<open><bas>ABC10</bas><stat>1</stat></open>
<open><bas>ABC11</bas><stat>4</stat><line>1234</line></open>
<new>
</new>

Upvotes: 1

Nic3500
Nic3500

Reputation: 8621

Assuming the file original.txt contains:

<open>
<bas>ABC1</bas>
<stat>1</stat>
</open>
<open>
<bas>ABC10</bas>
<stat>1</stat>
</open>
<open>
<bas>ABC11</bas>
<stat>4</stat>
<line>1234</line>
</open>
<new>
</new>

And so.bash contains:

#!/bin/bash

awk -f so.awk original.txt

and file so.awk contains:

BEGIN {
    inopen=0
}
/<open>/ {
    inopen=1
    printf "%s",$0
    next
}
/<\/open>/ {
    inopen=0
    print
    next
}
inopen==1 {
    gsub(" ", "")
    printf "%s",$0
    next
}
{ print }

The output will be:

<open><bas>ABC1</bas><stat>1</stat></open>
<open><bas>ABC10</bas><stat>1</stat></open>
<open><bas>ABC11</bas><stat>4</stat><line>1234</line></open>
<new>
</new>
  • When it sees <open>: set variable inopen to 1, print the line without a carriage return.
  • When it sees </open>: set variable inopen to 0, print the line with a carriage return.
  • When inopen == 1: remove any prefix spaces, print the result without a carriage return.
  • For all other lines, print them with no modification.

Upvotes: 2

Related Questions