开发者

remove new line if next line does not begin with a number

I have a file that is like

    1 test
    test

How can I remove the new line fro开发者_运维百科m the so the final output becomes:

1 test test

I already tried some sed but I could not het it to work.


This should do the trick:

sed -n '$!{ 1{x;d}; H}; ${ H;x;s|\n\([^0-9]\)| \1|g;p}' inputfile

Input:

1 test1
test1
2 test2
test2
test2
3 test3
4 test4

Output:

1 test1 test1
2 test2 test2 test2
3 test3
4 test4


You can be a bit smarter and print a new line before the line if it starts with a digit (except for the first line);

awk 'BEGIN{ORS="";} NR==1 { print; next; } /^[[:digit:]]/ { print "\n"; print; next; } { print; }'

The awk script:

BEGIN { ORS=""; }                            # default: no newline between output records
NR==1 { print; next; }                       # first line: print
/^[[:digit:]]/ { print "\n"; print; next; }  # if starts with a digit: print newline before
{print;}                                     # other lines (next; has not been called yet)


That is pretty simple to accomplish with sed. Consider the file below

$ cat numbered                      
1 abc
def
ghi
2 jkl
mno
3 pqr
4 stu
vxw

The command sed '/^[0-9]/{N; s/\n/ /;}' numbered will do the trick:

$ sed '/^[0-9]/{N; s/\n/ /;}' numbered
1 abc def
ghi
2 jkl mno
3 pqr 4 stu
vxw

How it works: first, it verifies if the current line does start with a digit:

/^[0-9]/

The /^[0-9]/ is an address and matches only lines which starts with a digit. Iff some line matches it, the the command following the address will be executed.

In this case, this command is a {, which opens a function list. The function list will aggregate two or more commands as if they where only one. In this case, we have two commands in the function list. The first one is the N command:

N

This command appends a newline and the next line to the pattern space. The next line will not be considered anymore after the current cycle. The next command is s/// which replaces newlines by a space:

s/\n/ /

So, the newline appended by N will be replaced by a space. Then, we need just to close the function list with }. The result will be:

/^[0-9]/{
    N
    s/\n/ /
}

Since I've put all commands in one line for brevity, the commands inside the function list should be separated by semicolons:

/^[0-9]/{N;s/\n/ /;}

Note that if a line starting by a digit follows another line starting by a digit, the following line will be joined to the previous one and the command will apply to it.


A solution using 'sed':

Input file (infile):

1 test
test
2 two 
3 three
4 four
five 
six
7 seven
eight
9 nine

'Sed' program (script.sed):

/[0-9]\+/ {
        : a 
        N
        /\n[0-9]\+/ {
                P
                s/.*\n//
        }
        t a
}

y/\n/ /

Execution:

$ sed -f script.sed infile

Output:

1 test test
2 two
3 three
4 four five 
six
7 seven eight
9 nine
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜