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:
h;
stores the delimiter-less line insed
's hold buffer.n;
fetches another line, since we're reading backwards, this is the line that should be appended to.x;
exchange hold buffer and pattern buffer.H;
append pattern buffer to hold buffer.x;
exchange newly appended lines to pattern buffer, now there's two lines in one buffer.s/\n/ * /p;
replace the middle linefeed with a " * ", now there's only one longer line; and print.b
start again, leave the code block.
Re-reverse the file with tac
; done.