Split or join lines in Linux using sed

I have file that contains below information

$ cat test.txt 
Studentename:Ram
rollno:12
subjects:6
Highest:95
Lowest:65
Studentename:Krish
rollno:13
subjects:6
Highest:90
Lowest:45
Studentename:Sam
rollno:14
subjects:6
Highest:75
Lowest:65

I am trying place info of single student in single. i.e My output should be

Studentename:Ram rollno:12 subjects:6 Highest:95 Lowest:65
Studentename:Krish rollno:13 subjects:6 Highest:90 Lowest:45
Studentename:Sam rollno:14 subjects:6 Highest:75 Lowest:65.

Below is the command I wrote

cat test.txt | tr "\n" " " | sed 's/Lowest:[0-9]\+/Lowest:[0:9]\n/g'

Above command is breaking line at regex Lowest:[0-9] but it doesn't print the pattern. Instead it is printing Lowest:[0-9].

Please help

4 answers

  • answered 2018-02-13 01:09 Gilles Quenot

    Try this using :

    awk '{if ($1 !~ /^Lowest/) {printf "%s ", $0} else {print}}' file.txt
    

    Or shorter but more obfuscated :

    awk '$1!~/^Lowest/{printf"%s ",$0;next}1' file.txt
    

    Or correcting your command :

    tr "\n" " " < file.txt | sed 's/Lowest:[0-9]\+/&\n/g'
    

    Explanation: & is whats matched in the left part of substitution

  • answered 2018-02-13 01:18 John1024

    Try:

    $ sed '/^Studente/{:a; N; /Lowest/!ba; s/\n/ /g}' test.txt
    Studentename:Ram rollno:12 subjects:6 Highest:95 Lowest:65
    Studentename:Krish rollno:13 subjects:6 Highest:90 Lowest:45
    Studentename:Sam rollno:14 subjects:6 Highest:75 Lowest:65
    

    How it works

    /^Studente/{...} tells sed to perform the commands inside the curly braces only on lines that start with Studente. Those commands are:

    • :a

      This defines a label a.

    • N

      This reads in the next line and appends it to the pattern space.

    • /Lowest/!ba

      If the current pattern space does not contain Lowest, this tells sed to branch back to label a.

      In more detail, /Lowest/ is true if the line contains Lowest. In sed, ! is negation so /Lowest/! is true if the line does not containLowest. Inba, thebstands for the branch command anda` is the label to branch to.

    • s/\n/ /g

      This tells sed to replace all newlines with spaces.

  • answered 2018-02-13 02:07 PesaThe

    Another possible GNU sed that doesn't assume Lowest is the last item:

    sed ':a; N; /\nStudent/{P; D}; s/\n/ /; ba' test.txt
    

  • answered 2018-02-13 10:13 potong

    This might work for you (GNU sed):

    sed '/^Studentename:/{:a;x;s/\n/ /gp;d};H;$ba;d' file
    

    Use the hold space to gather up the fields and then remove the newlines to produce a record.