0

I would like to combine two lines whenever the particular string is found in the file.

Sample Input:

{
    id: 23281598
      total: {
        value: 3.0
      }
      isThin: false
      raw: {
        value: 6.0
      }
    }
    total: {
      value: 1.401326182E9
    }
    Pools: {
      value: 8.98886247E8

Desired Output:

{
    id: 23281598
      total: { value: 3.0
      }
      isThin: false
      raw: { value: 6.0
      }
    }
    total: { value: 1.401326182E9
    }
    Pools: { value: 8.98886247E8

As you notice, whenever i find the pattern value: I want to combine it with previous line in the file. I am okay if you remove the leading white spaces in each line. I need awk or sed solution. There is no fixed pattern in the input file. The line containing value: may occur anywhere but it will not occur consecutively.

Using Solaris 5.10.

  • Is this actually a JSON file? In that case, the newlines does not matter (to a proper JSON parser). – Kusalananda Mar 1 '18 at 17:41
1

POSIXLY:

LC_ALL=C sed -e '$!N;/value:/b1' -e 'P;D' -e:1 -e 's/\n[[:space:]]*/ /' <file

It's straight forward:

  • $!N: with each line except the last one, reading the next line
  • /value:/b1: if pattern matches, go to branch named 1
  • P;D: if pattern does not match, print the current line, start new cycle with reading line from $!N above. So if you have line1\nline2, then print line1, start new cycle with line2, $!N make it to be line2\nline3 and so on.
  • :1: defines branch named 1
  • 's/\n[[:space:]]*/ /': in branch 1, replace embedded newline and leading spaces with one space.
1

Keep it simple:

sed 'N;s/\n[[:space:]]*value:/ value:/;P;D'

Do an N;P;D cycle to always process two lines at once (no $! needed here btw). Inside replace a newline with spaces followed by value: with a single whitespace. That's it.

  • I think you can use [[:blank:]] here... – don_crissti Mar 1 '18 at 18:37
0

You can try using sed also

sed -e '/: {$/{N;s/\n//g}' -e 's/{.*v/{ v/g' file

Explanation:

  • / start condition
  • : {$ if line ends with : {
  • / End condition
  • { Start operation group
  • N; concatenate the line below to the matching line
  • s/\n//g makes the replacement of \n
  • } End operation group

Optional for formatting output

  • 's/{.*v/{ v/g' execute other expression where replace all between {&v (spaces) to one single space

Is my understanding solaris doesn't support -i option, so you must do a redirection of the output to make the changes.

Give a try

  • You realized that only lines with value: should be joined? In this example there are no other cases, but think of something like name: {\n string: "tachomi"\n}. And your s/{.*v/{ v/g is really dangerous. – Philippos Mar 1 '18 at 17:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.