Hiểu các tệp AWK và CSV
Làm cách nào để viết chương trình AWK phân tích danh sách các trường trong tệp CSV, đếm số lượng của từng chuỗi khác nhau trong trường được chỉ định và in ra số lượng của từng chuỗi được tìm thấy? Tôi chỉ viết mã bằng C và Java, vì vậy tôi hoàn toàn nhầm lẫn về cú pháp của AWK. Tôi hiểu khái niệm đơn giản nhất, tuy nhiên, AWK được cấu trúc khác nhiều. Bất cứ lúc nào cũng được đánh giá cao, cảm ơn bạn!
BEGIN {
FS = ""
}
{
for(i = 1; i <= NF; i++)
freq[$i]++
PROCINFO ["sorted_in"] = "@val_num_desc" #this got the desired result
}
END {
for {this in freq)
printf "%s\t%d\n", this, freq[this]
}
Trên tệp CSV có chứa:
Field1, Field2, Field3, Field4
A, B, C, D
A, E, F, G
Z, E, C, D
Z, W, C, Q
Tôi có thể nhận được kết quả:
A 2
B 1
C 3
Q 1
D 1
E 2
F 1
, 12
G 1
W 1
Field1,Field2,Field3,Field4 1
Z 2
Đây là kết quả mong muốn:
A 10
C 7
D 2
E 2
Z 2
B 1
Q 1
Field1 1
Field2 1
F 1
Field3 1
G 1
Field4 1
W 1
Có một chỉnh sửa đối với mã của tôi được nhận xét.
Trả lời
Đã sửa mã của bạn:
$ awk ' BEGIN { # you need BEGIN block for FS FS = ", *" # your data had ", " and "," seps } # ... based on your sample output { for(i = 1; i <= NF; i++) freq[$i]++
}
END {
for(this in freq) # fixed a parenthesis
printf "%s\t%d\n", this, freq[this]
}' file
Đầu ra (sử dụng awk GNU. Các awk khác hiển thị đầu ra theo thứ tự khác):
A 2
B 1
C 3
Q 1
D 2
Field1 1
E 2
Field2 1
F 1
Field3 1
G 1
Field4 1
W 1
Z 2
AWK thực sự không phải là công cụ phù hợp cho công việc này. Mặc dù AWK có thể giải thích dữ liệu được phân tách bằng Dấu phẩy hoặc Tab, nhưng nó không có khái niệm về trường bao bọc hoặc thoát. Vì vậy, nó có thể xử lý một ví dụ đơn giản như:
Month,Day
January,Sunday
February,Monday
nhưng sẽ thất bại với ví dụ hợp lệ này:
Month,Day
January,"Sunday"
February,"Monday"
Do đó, tôi khuyên bạn nên xem xét một ngôn ngữ khác. Một cái gì đó giống như Python:
import csv
o = open('a.csv')
for m in csv.DictReader(o):
print(m)
https://docs.python.org/library/csv.html
Hoặc Ruby:
require 'csv'
CSV.table('a.csv').each do |m|
p m
end
https://ruby-doc.org/stdlib/libdoc/csv/rdoc/CSV.html
Hoặc thậm chí PHP:
<?php
$r = fopen('a.csv', 'r'); $a_head = fgetcsv($r); while (true) { $a_row = fgetcsv($r); if (feof($r)) {
break;
}
$m_row = array_combine($a_head, $a_row); print_r($m_row);
}
https://php.net/function.fgetcsv