Awk/sed replace newlines Awk/sed replace newlines shell shell

Awk/sed replace newlines


$ cat tst.awkBEGIN { FS=OFS="|" }NR==1 { reqdNF = NF; printf "%s", $0; next }{ printf "%s%s", (NF < reqdNF ? " " : ORS), $0 }END { print "" }$ awk -f tst.awk file.csvFIRST_NAME|LAST_NAME|NOTESJohn|Smith|This is a field with a newlineFoo|Bar|Baz

If that's not what you want then edit your question to provide more truly representative sample input and associated output.


Based on the assumption that the last field may contain one newline. Using tac and sed:

tac file.csv | sed -n '/|/!{h;n;x;H;x;s/\n/ * /p;b};p' | tac 

Output:

FIRST_NAME|LAST_NAME|NOTESJohn|Smith|This is a field with a * newlineFoo|Bar|Baz

How it works. Read the file backwards, sed is easier without forward references. If a line has no '|' separator, /|/!, run the block of code in curly braces {};, otherwise just p print the line. The block of code:

  1. h; stores the delimiter-less line in sed's hold buffer.
  2. n; fetches another line, since we're reading backwards, this is the line that should be appended to.
  3. x; exchange hold buffer and pattern buffer.
  4. H; append pattern buffer to hold buffer.
  5. x; exchange newly appended lines to pattern buffer, now there's two lines in one buffer.
  6. s/\n/ * /p; replace the middle linefeed with a " * ", now there's only one longer line; and print.
  7. b start again, leave the code block.

Re-reverse the file with tac; done.