Nhận danh sách tên tệp và so sánh với tệp csv trong khi thêm cột thứ 2 và 3 của cùng một cột thứ nhất

Aug 15 2020

Tôi có một tệp csv trông giống như sau:

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

và thư mục có tệp trống được đặt tên theo người dùng

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

Tôi muốn tìm kiếm tệp và lưu tên của nó vào một mảng, sau đó tìm kiếm tên đó thông qua bản ghi csv, thêm tất cả cột thứ 2 và thứ 3 của tên đó, cho tất cả các hàng và cũng hiển thị nếu giá trị người dùng vượt quá ví dụ: 400

Kết quả ví dụ:

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

Tôi thực sự đánh giá cao một số sự giúp đỡ. Hiện tại tôi đang thử với điều này, nhưng không có kết quả:

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

Hoặc có thể có một phương pháp đơn giản hơn mà không cần lưu tên tệp vào một mảng?

Trả lời

Quasímodo Aug 15 2020 at 20:13

Tôi đề nghị

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

Hoặc ở dạng unwinded, tương đương:

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

Đối với mỗi tệp bên trong dir/, tên cơ sở của nó (tức là tên không có đường dẫn) được chuyển đến tập lệnh awk dưới dạng biến f.

Trong tập lệnh awk, dấu phân tách trường được đặt thành dấu phẩy với -F ','. Sau đó, nếu trường đầu tiên của dir.csvbằng fthì tổng của trường thứ 2 và thứ 3 sẽ được thêm vào s. Nếu tổng vượt quá 400, thông báo sẽ được bao gồm.