Append to the previous line for a match

2019-02-28 00:33发布

can I use sed or awk to append to the previous line if a match is found ?

I have a file which has the format :

          INT32
          FSHL (const TP  Buffer)
             {
          INT32
          FSHL_lm (const TP  Buffer) 
          { WORD32 ugo = 0; ...

What I am trying to do is scan for independant open braces {and append it to the previous non-blank line .The match should not occur for an open brace appended by anything in the same line .

The expected output :

           INT32
          FSHL (const TP  Buffer){
          INT32
          FSHL_lm (const TP  Buffer) 
          { WORD32 ugo = 0; ...

Thanks for the replies .

标签: bash shell sed awk
4条回答
Summer. ? 凉城
2楼-- · 2019-02-28 01:16

This might work for you (GNU sed):

sed '$!N;s/\n\s*{\s*$/{/;P;D' file

Explanation:

  • $!N unless the last line append the next line to the pattern space.
  • s/\n\s*{\s*$/{/ replace a linefeed followed by no or any amount of white space followed by an opening curly brace followed by no or any amount of white space to the end of the string, by an opening curly brace.
  • P print upto and including the first newline.
  • D delete upto and including the first newline (if so do not start a new cycle).
查看更多
Anthone
3楼-- · 2019-02-28 01:19

[shyam@localhost ~]$ perl -lne 's/^/\n/ if $.>1 && /^\d+/; printf "%s",$_' appendDateText.txt

that will work

i/p:

06/12/2016 20:30 Test Test Test

TestTest

06/12/2019 20:30 abbs abcbcb abcbc

06/11/2016 20:30 test test

i123312331233123312331233123312331233123312331233Test

06/12/2016 20:30 abc

o/p:

06/12/2016 20:30 Test Test TestTestTest

06/12/2019 20:30 abbs abcbcb abcbc

06/11/2016 20:30 test ##testi123312331233123312331233123312331233123312331233Test

查看更多
老娘就宠你
4楼-- · 2019-02-28 01:36

One way using perl. I read all file in slurp mode and use a regular expression to search lines with only a curly brace and remove its leading spaces.

perl -ne '
    do {
        local $/ = undef;
        $data = <>;
    };
    $data =~ s/\n^\s*(\{\s*)$/\1/mg;
    print $data
' infile

Assuming infile with the content of the question, output will be:

FSHL (const TP  Buffer){
INT32
FSHL_lm (const TP  Buffer)
{ WORD32 ugo = 0; ...
查看更多
干净又极端
5楼-- · 2019-02-28 01:37

One way using awk:

awk '!(NF == 1 && $1 == "{") { if (line) print line; line = $0; next; } { sub(/^[ \t]+/, "", $0); line = line $0; } END { print line }' file.txt

Or broken out on multiple lines:

!(NF == 1 && $1 == "{") { 
    if (line) print line
    line = $0
    next
}

{
    sub(/^[ \t]+/, "", $0)
    line = line $0
}

END {
    print line
}

Results:

INT32
          FSHL (const TP  Buffer){
          INT32
          FSHL_lm (const TP  Buffer) 
          { WORD32 ugo = 0; ...

HTH

查看更多
登录 后发表回答