だから私はCSVファイルをパラメータとして受け入れ、2つの固有値を持つすべてのフィールドを削除するこのスクリプトを作成しました。とにかく私が扱うデータは各フィールドに2つの値があるからです。これがRedditデータの外観です。
基本的に私がすることは、カットループを使用して各列を繰り返し、各列を一意に並べ替え、2より小さい場合はその列番号を保存することです。次に、書き留めたすべての列番号を繰り返して削除するビッグカットコマンドを生成します。
問題は、大容量ファイルを処理するときに実行が非常に遅いことです。
可能であればスピードアップしたいのですが、高度なコマンドを使用することに慣れていません。誰かが私にこれを達成するためのより速い方法を示すことができれば私は嬉しいです!ありがとうございます。
パスワード:
#!/bin/bash
#find number of fields
num_items=$(cat $1 | head -n 1 | grep -o , | wc -w)
num_items=$((num_items + 0))
echo "Searching all $num_items columns for redundancy"
cols=()
command="-f"
for ((i = 1; i < $num_items; i++))
do
num_vals=$(cat $1 | cut -d, -f$i | sort -u | wc -w)
x=$(($num_vals+0))
#remove column if it has less than 2 values in its column
#lt 3 as we want to discard the field name at the top
if [ $x -lt 3 ]
then
cols+=("$i")
fi
bit="$i-$i,"
command="${command}${bit}"
done
command="${command}$num_items-$num_items"
echo ""
for col in "${cols[@]}"; do
sed_reg="s/$col-$col,//"
command=$(echo "$command" | sed $sed_reg)
echo "col $col has been removed"
done
command="cut -d, ${command} $1"
$command > pruned_cols.csv
より小さいサンプルデータ:https://ufile.io/27bm31d6
〜70,000行。サンプル:https://ufile.io/qvglxajr
システム:zshを使用するmacOS
答え1
これがあなたにどのように役立つかを確認してください。
$ cut --complement -d, -f$(awk -F, '
NR > 1 {for (i=1; i<=NF; i++) CNT[i, $i]++
}
END {for (c in CNT) if (CNT[c] == (NR-1)) {split (c, T, SUBSEP)
printf "%s%d", DL, T[1]
DL = ","
}
}
' /tmp/small_data.csv) /tmp/small_data.csv
あなたのcut
バージョンに対応するオプションがあるとします--complement
。それ以外の場合は、印刷ロジックを逆にします。そのセクションで失敗した場合は、awk
行ごとの処理を維持してください。NR
END
すべての行(タイトルを除く)のすべてのフィールドを調べて、一意のコンテンツを計算します。そのEND
セクションの行数CNT
からヘッダーを引いたものと同じ場合(つまり、フィールドのすべての行に同じ内容がある場合)、インデックスを分割してフィールド番号を印刷します。