I have a file that is like
1 test test
How can I remove the new line from the so the final output becomes:
1 test test
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
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.
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