
複数の列と1000のレコードを含むCSVファイルがあり、列の1つ(2番目の列であると仮定)のすべての値の前にアポストロフィを追加する必要があります。'
最初の行やヘッダー行に加えて、単純な行があるかもしれません。awk
またはを使用してどのようにこれを達成できますかsed
?二重引用符で囲まれた値には、複数のカンマを含めることができます。
サンプル:
"col1","col2","col3","col4","col5"
"value11","value12","value13","value14","value15"
"value21","value22","value23","value24","value25"
"value31","value32","value33","value34","value35"
予想出力:
"col1","col2","col3","col4","col5"
"value11","'value12","value13","value14","value15"
"value21","'value22","value23","value24","value25"
"value31","'value32","value33","value34","value35"
答え1
sed:
sed '2,$s/^\("[^"]*","\)/\1'"'"/ test.in
一部のエスケープを削除するには、ERE を使用します。
sed -E '2,$s/^("[^"]*",")/\1'"'"/ test.in
奇妙な:
awk -F, 'NR>1{sub(/^"/,"\"'"'"'",$2)}1' test.in
引用を心配しない場合は、エスケープコードを使用してください。
awk -F, '{sub(/^"/,"\"\x27",$2)}1' test.in
答え2
パールの使用:
perl -pi -e '
BEGIN{
$column_number = 2; # Change as needed
$column_number--;
$apostrophe = chr 39;
}
next unless $this_is_data++; # Skip the first line
s@ ^((?:"[^"]+"\s*,){$column_number}) "@$1"$apostrophe@x
' your_file
これは、フィールドにバックスラッシュでエスケープされた引用符が含まれていないと仮定します。
答え3
愚か者の使い方は次のとおりです。
$ gawk -F'","' -v var="'" -v OFS='","' 'NR>1{$2=var$2;} 1' foo.csv
この-v
オプションを使用すると、スクリプトにアクセスできる変数を定義できますgawk
。この場合、var
is'
とOFS
(出力フィールド区切り記号)は","
入力フィールド区切り記号(-F
)と同じです。次に、これが最初の行()ではないことを確認し、2番目の列にNR>1
値を追加します。var
結局、これは1
ただのトリックであり、真と評価され、対応する行gawk
が印刷されます。 1つを追加するのと同じですprint;
が、短いです。
別の列でこれを実行するには、$2=var$2;
目的の列番号に変更するだけです$N=var$N
。N
Perlでもこれを行うことができます(もちろん、次のようにすることもできます)。すべてパールから):
$ perl -F'\",\"' -ane '$.>1 && do{$F[1]=chr(39).$F[1]};
print join("\",\"",@F)' foo.csv
この-a
スイッチは、perlがgawkのように入力ラインを分割し、単に配列に格納するようにします(perl配列は0から始まるので、2番目の列は、3番目の列は等に@F
なります)。 (再度同様) 入力フィールドの区切り記号を設定します。したがって、行番号が1()より大きいことを確認し、そうであれば(a、thanks @josephR)値を追加します。最後に、結果文字列を使用して配列の各要素を連結して印刷します。$F[1]
$F[2]
-F
gawk
$.>1
chr 39
'
join
@F
","
答え4
簡単な方法はsed
次のとおりです。
$ sed 's/","/","\x27/' afile
"col1","'col2","col3","col4","col5"
"value11","'value12","value13","value14","value15"
"value21","'value22","value23","value24","value25"
"value31","'value32","value33","value34","value35"
詳細
私たちは最初の発生を検索し、","
それに置き換えます","`
。しかし、バックティックをエスケープするのは難しいかもしれません。したがって、対応する16進エスケープコードを入力するだけです\x27
。
あなたの問題
必要な行だけを変更するように制限するために、このように調整できます。
$ cat <(head -n +1 afile) <(tail -n +2 afile | sed 's/","/","\x27/')
"col1","col2","col3","col4","col5"
"value11","'value12","value13","value14","value15"
"value21","'value22","value23","value24","value25"
"value31","'value32","value33","value34","value35"
sed
あるいは、ヒント8-)を知っている場合は、最初の行を完全にスキップできます。
$ sed '2,$s/","/","\x27/' afile
"col1","col2","col3","col4","col5"
"value11","'value12","value13","value14","value15"
"value21","'value22","value23","value24","value25"
"value31","'value32","value33","value34","value35"
これはsed
、最後の行($
)までの2番目の行を選択し、検索と置換で実行することを意味します。