Ottieni un elenco di nomi di file e confrontali con un file CSV aggiungendo la seconda e la terza colonna della stessa prima colonna

Aug 15 2020

Ho un file CSV simile a questo:

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

e una directory che ha un file vuoto chiamato dopo l'utente

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

Voglio cercare il file e salvare il suo nome in un array, quindi cercare quel nome attraverso il record csv, aggiungere tutta la seconda e la terza colonna di quel nome, per tutte le righe, e mostra anche se il valore dell'utente supera ex: 400

Risultati di esempio:

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

Apprezzerei davvero un aiuto. Attualmente sto provando con questo, ma nessun risultato:

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

O forse esiste un metodo più semplice in cui non è necessario salvare il nome del file in un array?

Risposte

Quasímodo Aug 15 2020 at 20:13

suggerisco

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

O in forma non srotolata ed equivalente:

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

Per ogni file all'interno dir/, il suo nome di base (cioè il nome senza il percorso) viene passato allo script awk come variabile f.

Nello script awk, il separatore di campo è impostato su virgola con -F ','. Quindi, se il primo campo di dir.csvè uguale a f, viene aggiunta la somma dei campi 2 ° e 3 ° s. Se la somma supera 400, il messaggio viene incluso.