次の形式のファイルがあります。
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
これは「演算子の左側に一致するすべて」を意味する&
特殊変数です。sed
s///
答え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」(フィールドを含む区切り文字または改行なし)として扱うという点で同じです。
与えられた数値文字列を分割します。ここで、各数字は参照する必要があるフィールドに対応します。次にフィールドを繰り返し、引用符を追加して各フィールドを変更します。