前の質問: "囲む引用符に加えて、文字列の間に二重引用符があります。「次のようなCSVエントリを取得したい@BernieReiterは、次の質問をしました。
$ cat test.csv
17,"abc","Testurteil "sehr gut"","08/15"
99,"xyz","Testurteil "vernichtend"","4711"
"..."
挿入された二重引用符()の代わりに一重引用符()に変換します'...'
。
結果は次のようになります。
17,"abc","Testurteil 'sehr gut'","08/15"
99,"xyz","Testurteil 'vernichtend'","4711"
@BernieReiterは@StephaneChazelasのソリューションを問題にどのように適用できるかを尋ねました。ここで彼はこのPerlソリューションを使用しました。
$ perl -pi.back -le 's/"(?:[^"]|"(?=[^,]))*"|[^",]*/($r=$&)=~
s@(^"|"$|\\.)|"@$1||"\\\""@ge;$r/ge' file.csv
それでは、Stephenのソリューションを修正する方法は?
ベストアンサー1
@Stephaneのソリューションに対する次の修正は、@BernieReiterが探しているものを提供しているようです。
$ perl -pi.back -le 's/"(?:[^"]|"(?=[^,]))*"|[^",]*/($r=$&)=~
s@(^"|"$|\\.)|"@$1||"'\''"@ge;$r/ge' test.csv
もともとPerlソリューションで注目すべき重要な点は、次のサブコンポーネントです。
s@(^"|"$|\\.)|"@$1||"\\\""@ge
具体的には、次のコードは次のとおりです。
"\\\""
これは二重引用符ブロックで囲まれています\\\"
。これは\"
、内部二重引用符を置き換える@Stephaneの元のソリューションの一部です。何が起こるかは次のとおりです。
"Testurteil "sehr gut""
そしてこれを次のように変更してください。
"Testurteil \"sehr gut\""
したがって、二重引用符()の間を"\\\""
一重引用符構造に置き換えます。
"'\''"
メモ:\'
これを保護するには、一重引用符で囲む必要があります!
最後の解決策
$ perl -pi.back -le 's/"(?:[^"]|"(?=[^,]))*"|[^",]*/($r=$&)=~
s@(^"|"$|\\.)|"@$1||"'\''"@ge;$r/ge' file.csv
はい
このコマンドを実行すると、ファイルは元の指定どおりに変換されます。
$ perl -pi.back -le 's/"(?:[^"]|"(?=[^,]))*"|[^",]*/($r=$&)=~
s@(^"|"$|\\.)|"@$1||"'\''"@ge;$r/ge' test.csv
結果:
$ more test.csv
17,"abc","Testurteil 'sehr gut'","08/15"
99,"xyz","Testurteil 'vernichtend'","4711"