n番目のカンマの前後の引用符の追加

n番目のカンマの前後の引用符の追加

次の形式のファイルがあります。

a1,b1,c1,d1,e1,f1
a2,b2,c2,d2,e2,f2

特定の列(たとえば、a列とd列、列)の周りに引用符( ")を追加したいと思います。欲しくない他のカンマを含みますが、長さが異なります)次のような結果が得られます。

"a1",b1,c1,"d1",e1,f1
"a2",b2,c2,"d2",e2,f2

何度も繰り返しながら、次のことを試しました。列の開始か終了かによって、カンマ(、)をカンマ+引用符(、")または引用+カンマ("、)に置き換えました。

sed -E 's/(([^,]*,){1}[^,]*),/\1\,\"/g'

ただし、これはすべての2番目のカンマをカンマと引用符で置き換えますが、各コマンドは引用符が追加されている限り、場所だけを制御したいと思います。

答え1

まず、すべての項目を置き換える必要はなく、gこれは「グローバルに」を意味し、列を指定する必要があるため、すべてを変更したくありません。次に、sed次のようにN番目の発生を対象とします。 N番目の発生はs/old/new/Nどこにありますか?Nしたがって、4番目のフィールドを参照するには、次のようにします。

$ sed 's/[^,]*/"&"/4' file 
a1,b1,c1,"d1",e1,f1
a2,b2,c2,"d2",e2,f2

最初のフィールドを変更します。

$ sed 's/[^,]*/"&"/1' file 
"a1",b1,c1,d1,e1,f1
"a2",b2,c2,d2,e2,f2

これは「演算子の左側に一致するすべて」を意味する&特殊変数です。seds///

答え2

awkフィールドに適しています(自分自身はあまり良くありません。これは1と4ではなく、フィールド1と3で動作します)。

Awk='{
    sub(/.*/, Dq "&" Dq, $1);
    sub(/.*/, Dq "&" Dq, $3);
    print;
}'

$ awk -v FS=, -v OFS=, -v Dq='"' "${Awk}" <<'[][]'
a1,b1,c1,d1,e1,f1
a2,b2,c2,d2,e2,f2
[][]

"a1",b1,"c1",d1,e1,f1
"a2",b2,"c2",d2,e2,f2

答え3

参照するフィールドのリストを渡す

awk -v fields='1,4' '
    BEGIN {
        FS = OFS = ","
        n = split(fields, fs)
    }
    { for (i=1; i<=n; i++) $(fs[i]) = "\"" $(fs[i]) "\"" }
    { print }
' file
"a1",b1,c1,"d1",e1,f1
"a2",b2,c2,"d2",e2,f2

答え4

使用awkするミラーmlr)、参照するフィールド番号は、コマンドラインにカンマ区切りのリストとして提供されます。

$ awk -F, -v f=1,4,5 'BEGIN { OFS=FS; split(f,a,",") } { for (i in a) $a[i] = "\"" $a[i] "\"" };1' file
"a1",b1,c1,"d1","e1",f1
"a2",b2,c2,"d2","e2",f2
$ mlr --nidx --fs comma put -s f=1,4,5 'begin { @a=splitnv(@f,",") } for (k,v in @a) { $[v] = "\"" . $[v] . "\"" }' file
"a1",b1,c1,"d1","e1",f1
"a2",b2,c2,"d2","e2",f2

両方とも、入力をカンマ区切りレコードセットの「単純なCSV」(フィールドを含む区切り文字または改行なし)として扱うという点で同じです。

与えられた数値文字列を分割します。ここで、各数字は参照する必要があるフィールドに対応します。次にフィールドを繰り返し、引用符を追加して各フィールドを変更します。

関連情報