This is a little tricky with just regular expressions, but it can be done in several steps. Here's the perl script that I used for this (sed can't be used because I used lookaheads):
perl -pe 's/(?:(?:\||^)[ ]*"(.*?)\"[ ]*(?=\||$))/~~\1~~/gm;s/"/""/g;s/~~(.*?)~~/~~"\1"~~/g;s/~~~~/|/g;s/~~//g' inputfile.txt
(use perl -pi -e if you want to edit the input file)
The script does the following steps:
- Look for everything that either is inside of |"{...}"|, (start of line)"{...}"|, or |"{...}"(end of line), ignoring spaces outside of the text. Replace the outside bits with ~~(I used something that is known not to be inside of the text)
- Replace all remaining quotation marks with doubled-up ones
- Replace all internal ~~{...}~~sequences with~~"{...}"~~
- Replace all ~~~~sequences (which will all be internal) to|
- Remove all remaining ~~sequences (which will be at the beginning and end of the lines)
Running each step given the following test text:
"164829" | "collection 1" | "wood plank 2" x 4" long" | "23.5"
"939485"|"collect "name""|"more items with | " and ""|"294.5""
We get the following output after each step:
$ perl -pe 's/(?:(?:\||^)[ ]*"(.*?)\"[ ]*(?=\||$))/~~\1~~/gm;' testinput.txt                       
~~164829~~~~collection 1~~~~wood plank 2" x 4" long~~~~23.5~~
~~939485~~~~collect "name"~~~~more items with | " and "~~~~294.5"~~
$ perl -pe 's/(?:(?:\||^)[ ]*"(.*?)\"[ ]*(?=\||$))/~~\1~~/gm;s/"/""/g;' testinput.txt
~~164829~~~~collection 1~~~~wood plank 2"" x 4"" long~~~~23.5~~
~~939485~~~~collect ""name""~~~~more items with | "" and ""~~~~294.5""~~
$ perl -pe 's/(?:(?:\||^)[ ]*"(.*?)\"[ ]*(?=\||$))/~~\1~~/gm;s/"/""/g;s/~~(.*?)~~/~~"\1"~~/g;' testinput.txt
~~"164829"~~~~"collection 1"~~~~"wood plank 2"" x 4"" long"~~~~"23.5"~~
~~"939485"~~~~"collect ""name"""~~~~"more items with | "" and """~~~~"294.5"""~~
$ perl -pe 's/(?:(?:\||^)[ ]*"(.*?)\"[ ]*(?=\||$))/~~\1~~/gm;s/"/""/g;s/~~(.*?)~~/~~"\1"~~/g;s/~~~~/|/g;' testinput.txt
~~"164829"|"collection 1"|"wood plank 2"" x 4"" long"|"23.5"~~
~~"939485"|"collect ""name"""|"more items with | "" and """|"294.5"""~~
$ perl -pe 's/(?:(?:\||^)[ ]*"(.*?)\"[ ]*(?=\||$))/~~\1~~/gm;s/"/""/g;s/~~(.*?)~~/~~"\1"~~/g;s/~~~~/|/g;s/~~//g' testpipe.txt
"164829"|"collection 1"|"wood plank 2"" x 4"" long"|"23.5"
"939485"|"collect ""name"""|"more items with | "" and """|"294.5"""
     
    
sedto alter the file and need to work with the text on the command line. If that's the case, you can just escape it with backslashes or single quotes.