データファイル内の特定の二重引用符のみを置き換える

データファイル内の特定の二重引用符のみを置き換える

パイプを列区切り文字として使用し、二重引用符をテキスト区切り文字として使用して、データベースからフラットファイルにデータを抽出しています。

データファイルは次のとおりです。

"164829" | "collection 1" | "wood plank 2" x 4" long" | "23.5" 
"2017"|"S"|"221318"|"WE"|"20170118"|"Someones name"|"20170215"|"1785"|"009"|"20170215"|"182339"|"99536"|"00090"|"LOCAL00"|"930N"|"2017"|"6100"|"0000880"|1.000|0.000|"EA"|" "|" "|" "|" "|"005"|"00000000"|" "|" "|"1785"|"50228"|"R"|"2017"|"NMT CAUTION| 5" X 3" NAT ON BLK"|" "|" "|"USD"|"7444"|" "|"000"|"COIN"|"04"|35.00|"00"

2番目の二重引用符でデータ(テキスト区切り文字を除く)をエスケープできるすべてのケースを見つけるためのコマンド/スクリプトは何ですか?

最終結果は次のようになります。

"164829" | "collection 1" | "wood plank 2"" x 4"" long" | "23.5"
"2017"|"S"|"221318"|"WE"|"20170118"|"Someones name"|"20170215"|"1785"|"009"|"20170215"|"182339"|"99536"|"00090"|"LOCAL00"|"930N"|"2017"|"6100"|"0000880"|1.000|0.000|"EA"|" "|" "|" "|" "|"005"|"00000000"|" "|" "|"1785"|"50228"|"R"|"2017"|"NMT CAUTION| 5"" X 3"" NAT ON BLK"|" "|" "|"USD"|"7444"|" "|"000"|"COIN"|"04"|35.00|"00"

答え1

正規表現だけを使用すると少しトリッキーですが、いくつかのステップを経て完了することができます。ここに私が使用するPerlスクリプトがあります(予測を使用しているため、sedは使用できません)。

perl -pe 's/(?:(?:\||^)[ ]*"(.*?)\"[ ]*(?=\||$))/~~\1~~/gm;s/"/""/g;s/~~(.*?)~~/~~"\1"~~/g;s/~~~~/|/g;s/~~//g' inputfile.txt

perl -pi -e入力ファイルを編集したい場合に使用)

スクリプトは次の手順を実行します。

  1. 外部の空白のテキストを無視して |"{...}"|(行を開始) "{...}"|または |"{...}" (行末) 内のすべての項目を検索します。外部ビットを次に置き換えます~~。 (テキスト内部にないことが知られているものを使用しました。)
  2. 残りの引用符をすべて二重引用符で置き換えます。
  3. すべての内部~~{...}~~シーケンスを次に置き換えます。~~"{...}"~~
  4. すべての~~~~シーケンス(すべての内部シーケンス)を次に置き換えます。|
  5. 残りのすべての~~シーケンスを削除する(行の始まりと終わり)

各ステップが実行され、次のテストテキストが提供されます。

"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;' 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"""

答え2

二重引用符は実際の二重引用符(「vs」)ではありません。
実際の二重引用符 "を使用すると、sedでこれを試すことができます(データに@がないと仮定)。

sed 's/" | "/@/g;s/"/""/g;s/^"//;s/"$//;s/@/" | "/g' infile

答え3

このフォーラムのBahratは問題解決に非常に近い答えを投稿しましたが、何とかこの投稿から削除されました(下記のコード)。唯一の問題は、文字列のパイプを処理できないことです(例:「25」|「データを接続するには1つを使用する必要があります」|「付録1」|20|「最後のエントリ」)。彼は今日投稿することになっていましたが、そのスレッドは削除されましたか?

awk -v FS='|' -v OFS='|' '{for(i=1;i<=NF;i++){gsub(/"/,"\"\"",$i);sub(/"/,"",$i);sub(/"[^"]*$/,"",$i)}print}' myfile > myfile3

答え4

入力 -

"2017"|"S"|"221318"|"私たち"|"20170118"|"誰かの名前"|"20170215"|"1785"|"009"|"20170215"|"182339"|"99536" | "00090"|"Local00"|"930N"|"2017"|"6100"|"0000880"|1.000|0.000|"EA"|""|""|""""""|"005"| "00000000" |" "|" "|"1785"|"50228"|"R"|"2017"|"NMT NOTE| 5" X 3" NAT ON BLK"|" "|" "|"USD"| |""|"000"|"コイン"|"04"|35.00|"00"

注文する:

  awk -v RS='[[:blank:]]*[[:blank:]]*[|][[:blank:]]*|[[:blank:]]*[\n][[:blank:]]*' '{ if ($0 !~ /(^"([^"]|"")*"$)/) { gsub(/\"/,"\"\"");sub(/^"/,"");sub(/"$/,"") } printf "%s%s", $0, RT}' file.txt

出力 -

"2017"|"S"|"221318"|"私たち"|"20170118"|"誰かの名前"|"20170215"|"1785"|"009"|"20170215"|"182339"|"99536" | "00090"|"Local00"|"930N"|"2017"|"6100"|"0000880"|1.000|0.000|"EA"|""|""|""""""|"005"| "00000000" |" "|" "|"1785"|"50228"|"R"|"2017"|"NMT NOTE|5""X 3""NAT ON BLK"|""|""|"USD "|" 7444"|""|"000"|"コイン"|"04"|35.00|"00"

関連情報