テキスト処理 - 各行の最初と最後の2番目を置き換えます。

テキスト処理 - 各行の最初と最後の2番目を置き換えます。

私のCSVファイルに問題があるため、引用符を追加する必要があります。

存在する

field,field2,text field with potential commas,field4,field5
field,field2,text fie,ld with pot,ential commas,field4,field5
field,field2,text field with, potential commas,field4,field5

出る

field,field2,"text field with potential commas",field4,field5
field,field2,"text fie,ld with pot,ential commas",field4,field5
field,field2,"text field with, potential commas",field4,field5

sed 's/,/,"/2'最初の引用符を追加します。しかし、最後から後ろに各行の2番目の項目に対して同じことをどのように実行しますか?

sed、awk、Perl、その他の方法の使用を歓迎します。ファイルには数百万行があり、高速です。

答え1

1つのアプローチは次のとおりですawk。 5つ以上のカンマ区切りフィールドがある場合は、それを連結する「中間」フィールドを繰り返してから、引用符で囲まれた新しいフィールドを印刷し、最後の2つのフィールドを印刷します。

awk -f awkscript.awk < input

次のようにawkscript.awk:

BEGIN {
  OFS=","
  FS=","
}
{
        if (NF > 5) {
                middle=""
                for(i=3; i <= NF-2; i++)
                        middle=(middle ? middle"," : "")$i
                print $1, $2, "\""middle"\"", $(NF-1), $NF
        } else {
                print $1, $2, "\""$3"\"", $4, $5
        }
}

答え2

これにより、sed次のことができます。

sed 's/,/,"/2; s/\(,[^,]*,[^,]*\)$/"\1/' infile

これはs/,/,"/22番目のものだけを置き換えます。これは、逆参照のグループ一致で行末で一致し、引用s/\(,[^,]*,[^,]*\)$符を追加した後、置換セクションから再度インポートされます。,anything-not-a-comma,anything-not-a-comma$\1"\1

答え3

これは非常に簡単なアプローチですが、おそらく最も効率的ではありません。

sed 's/,/,"/2' input.csv | rev | sed 's/,/,"/2' | rev > output.csv

答え4

sed -e '
   s/,/&\n/2
   s/\n\(.*\)\(,.*,.*\)/"\1"\2/
'    input.csv


 perl -pe '
    my $p;
    while ( /,/g ) {
       s/\G/"/,next if ++$p == 2;

       last if s/,\G(?=.*,)(?!.*,.*,)/",/;  # looks for 2nd last comma
    }
 '    input-file.csv



 perl -pe '
      substr($_, index($_, q/,/, 1+index($_, q/,/)), 1) = q/,"/;

      substr($_, rindex($_, q/,/, -1+rindex($_, q/,/)), 1) = q/",/;
 '     csvfile

ここでは、左から2番目のカンマの位置を取得するためにindex関数を2回呼び出します。これで位置が決定したので、substr関数を使用して隣に引用符を付けます。

今回もrindex関数を呼び出し、それに応じて変更します。

関連情報