Получите список имен файлов и сравните с файлом csv, добавляя 2-й и 3-й столбцы того же 1-го столбца

Aug 15 2020

У меня есть файл csv, который выглядит так:

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

и каталог, в котором есть пустой файл, названный в честь пользователя

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

Я хочу найти файл и сохранить его имя в массиве, затем выполнить поиск этого имени в записи csv, добавить все 2-й и 3-й столбцы этого имени для всех строк, а также показать, превышает ли значение пользователя ex: 400

Примеры результатов:

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

Буду очень признателен за помощь. В настоящее время я пытаюсь это сделать, но безрезультатно:

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

Или, может быть, есть более простой метод, при котором не нужно сохранять имя файла в массив?

Ответы

Quasímodo Aug 15 2020 at 20:13

Я предлагаю

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

Или в развернутой, эквивалентной форме:

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

Для каждого файла внутри dir/его базовое имя (т.е. имя без пути) передается сценарию awk в качестве переменной f.

В сценарии awk в качестве разделителя полей используется запятая с -F ','. Затем, если первое поле dir.csvравно f, сумма 2-го и 3-го полей добавляется s. Если сумма превышает 400, сообщение включается.