Dapatkan daftar nama file, dan bandingkan dengan file csv sambil menambahkan kolom ke-2 dan ke-3 dari kolom pertama yang sama

Aug 15 2020

Saya memiliki file csv yang terlihat seperti ini:

user1,400,300
user2,250,250
user3,400,300
user1,400,300
user4,400,300
user2,250,250

dan direktori yang memiliki file kosong dengan nama pengguna

$ ls /dir/*
/dir/user1
/dir/user2

Saya ingin mencari file dan menyimpan namanya ke dalam array, kemudian mencari nama itu melalui record csv, menambahkan semua kolom ke-2 dan ke-3 dari nama itu, untuk semua baris, dan juga menunjukkan jika nilai pengguna melebihi mis: 400

Hasil contoh:

user1,1400
user1 has exceed 400
user2,1000
user2 has exceed 400

Saya sangat menghargai bantuan. Saat ini saya mencoba dengan ini, tetapi tidak ada hasil:

shopt -s nullglob
cd /dir/
ARRAY=(*)

for ((i=0; i<${#ARRAY[@]}; i++)); do
    name=${ARRAY[i]} awk ' BEGIN{FS=OFS=","} {$name += (($2+$3))} 
    END{for (j in a) printf "%s | %0.2f\n", j, a[j]}
    ' /dir.csv
done
cd

Atau mungkin adakah metode yang lebih sederhana di mana tidak perlu menyimpan nama file ke dalam array?

Jawaban

Quasímodo Aug 15 2020 at 20:13

saya menyarankan

for f in dir/*; do awk -F ',' '$1==f{s+=$2+$3}END{print f","s;if(s>400)print f" has exceeded 400"}' f="$(basename "$f")" dir.csv; done

Atau dalam bentuk yang setara dan santai:

for f in dir/*; do 
    awk -F ',' '
        $1==f{s+=$2+$3}
        END{
            print f","s
            if(s>400)print f" has exceeded 400"
        }
    ' f="$(basename "$f")" dir.csv
done

Untuk setiap file di dalamnya dir/, nama dasarnya (yaitu, nama tanpa jalur) diteruskan ke skrip awk sebagai variabel f.

Dalam skrip awk, pemisah bidang disetel ke koma dengan -F ','. Kemudian, jika bidang pertama dir.csvsama dengan f, jumlah bidang ke-2 dan ke-3 ditambahkan ke s. Jika jumlahnya melebihi 400, pesan tersebut disertakan.