I have a text file with the following format. The first line is the \"KEY\" and the second line is the \"VALUE\".
KEY 4048:1736 string
3
KEY 0:1772 string
1
Here is my solution in bash:
while read line1; do read line2; echo "$line1, $line2"; done < data.txt
There are more ways to kill a dog than hanging. [1]
awk '{key=$0; getline; print key ", " $0;}'
Put whatever delimiter you like inside the quotes.
References:
perl -0pE 's{^KEY.*?\K\s+(\d+)$}{ $1}msg;' data.txt > data_merged-lines.txt
-0
gobbles the whole file instead of reading it line-by-line;
pE
wraps code with loop and prints the output, see details in http://perldoc.perl.org/perlrun.html;
^KEY
match "KEY" in the beginning of line, followed by non-greedy match of anything (.*?
) before sequence of
\s+
of any kind including line breaks;(\d+)
which we capture and later re-insert as $1
;followed by the end of line $
.
\K
conveniently excludes everything on its left hand side from substitution so { $1}
replaces only 1-2 sequence, see http://perldoc.perl.org/perlre.html.
Although it seems the previous solutions would work, if a single anomaly occurs in the document the output would go to pieces. Below is a bit safer.
sed -n '/KEY/{
N
s/\n/ /p
}' somefile.txt
nawk '$0 ~ /string$/ {printf "%s ",$0; getline; printf "%s\n", $0}' filename
This reads as
$0 ~ /string$/ ## matches any lines that end with the word string
printf ## so print the first line without newline
getline ## get the next line
printf "%s\n" ## print the whole line and carriage return
Another approach using vim would be:
:g/KEY/join
This applies a join
(to the line below it) to all lines that have the word KEY
in it. Result:
KEY 4048:1736 string 3
KEY 0:1772 string 1
KEY 4192:1349 string 1
KEY 7329:2407 string 2
KEY 0:1774 string 1