Hiểu các tệp AWK và CSV

Oct 20 2020

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

1 JamesBrown Oct 21 2020 at 03:35

Đã 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
StevenPenny Oct 21 2020 at 03:10

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