awkでcsv列を記録し、空のフィールドを考慮してください。

awkでcsv列を記録し、空のフィールドを考慮してください。

複数の列を含む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ファイル内の隣接するフィールド区切り文字(繰り返しカンマで表される空の列)を考慮しません,,,,。これをどのように考慮しますか?私は好きではない解決策はここにあります一般化がうまくいかないためです(条件確認が多いため、実際のアプリケーションはNF40より大きく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のすべての項目を下位バージョンに置き換えます。または
によってcutpaste

paste -d, <(cut -d, -f-4 file.csv) <(cut -d, -f5- file.csv | tr '[[:upper:]]' '[[:lower:]]')

おすすめ記事