複数の列を含むcsvファイルがあるとします。NF
一定ではありません。現在4より大きい列を小文字に置き換えるには、次のようにします。
#!/usr/bin/awk
#call with `awk -f lowercase.awk in.csv > out.csv`
BEGIN {
OFS=",";
FPAT="([^,]+)|(\"[^\"]+\")";
}
{
for (i=1; i<=NF; i++){
if(i>4 && $i){
$i = tolower($i);
}
}
print $0;
}
ただし、これはcsvファイル内の隣接するフィールド区切り文字(繰り返しカンマで表される空の列)を考慮しません,,,,
。これをどのように考慮しますか?私は好きではない解決策はここにあります一般化がうまくいかないためです(条件確認が多いため、実際のアプリケーションはNF
40より大きく70未満です)。
ユニットテスト:
入力.csv
apple,orange,banana,cherry,MELON,"Fruit salad",grape
"Lots of vegtables",CUCUMBER,carrot,potato,RADISH,BeetrOOT
Bread,BAGEL,,,,Croissant
出力.csv
apple,orange,banana,cherry,melon,"fruit salad",grape
"Lots of vegtables",CUCUMBER,carrot,potato,radish,beetroot
Bread,BAGEL,,,,croissant
答え1
完了しやすいsed
sed 's/\(\([^,]*,\)\{4\}\)\(.*\)/\1\L\3/' file.csv
エスケープ文字が気に入らない場合は、スクリプトを変更できます(GNU sedの場合)。
sed -r 's/(([^,]*,){4})(.*)/\1\L\3/' file.csv
コンマ以外の記号(0を含む)の4つのグループを見つけて、変更せずに()\1
文字列の残りの部分()内\3
のすべての項目を下位バージョンに置き換えます。または
によってcut
paste
paste -d, <(cut -d, -f-4 file.csv) <(cut -d, -f5- file.csv | tr '[[:upper:]]' '[[:lower:]]')
答え2
質問が間違って理解された可能性がありますのでご了承ください。tolower
しかし、4(または40または希望する項目)より大きいすべてのフィールドを簡単に処理できる必要があるようです。たとえば、
BEGIN {
OFS = ","
}
{
for (i = 4 ; i <= NF ; i++) {
$i = tolower($i)
}
$1 = $1
print
}
結局、tolower(*some empty field*)
それは完全に空でした。これがうまくいかない理由はありますか?
編集:私の結果:
apple,orange,banana,cherry,melon,"fruit salad",grape
"Lots of vegtables",CUCUMBER,carrot,potato,radish,beetroot
Bread,BAGEL,,,,croissant