tham gia nhiều dòng dựa trên cột1


8

Tôi có một tập tin như dưới đây ..

abc, 12345
def, text and nos    
ghi, something else   
jkl, words and numbers

abc, 56345   
def, text and nos   
ghi, something else 
jkl, words and numbers

abc, 15475  
def, text and nos 
ghi, something else
jkl, words and numbers

abc, 123345
def, text and nos
ghi, something else  
jkl, words and numbers

Tôi muốn chuyển đổi (tham gia) nó dưới dạng:

abc, 12345, 56345, 15475, 123345
def, text and nos, text and nos,text and nos,text and nos
ghi, something else, something else, something else, something else   
jkl, words and numbers, words and numbers, words and numbers, words and numbers

2
Bạn có thực sự có thêm dòng trống trong tệp đầu vào của bạn? Nếu không, vui lòng chỉnh sửa và xóa chúng, bạn sẽ hiển thị tệp chính xác như hiện tại.
terdon

Câu trả lời:


10

Nếu bạn không quan tâm đến thứ tự đầu ra:

$ awk -F',' 'NF>1{a[$1] = a[$1]","$2};END{for(i in a)print i""a[i]}' file 
jkl, words and numbers, words and numbers, words and numbers, words and numbers
abc, 12345, 56345, 15475, 123345
ghi, something else, something else, something else, something else
def, text and nos, text and nos, text and nos, text and nos

Giải trình

  • NF>1 có nghĩa là chúng ta chỉ cần xử lý cho dòng không trống.
  • Chúng tôi lưu tất cả trường đầu tiên trong mảng kết hợp a, với khóa là trường đầu tiên, giá trị là trường thứ hai (hoặc phần còn lại của dòng). Nếu khóa đã có giá trị đã được lưu, chúng ta sẽ ghép hai giá trị.
  • Trong ENDkhối, chúng tôi lặp qua mảng kết hợp a, in tất cả các khóa của nó với giá trị tương ứng.

Hoặc sử dụng perlsẽ giữ trật tự:

$perl -F',' -anle 'next if /^$/;$h{$F[0]} = $h{$F[0]}.", ".$F[1];
    END{print $_,$h{$_},"\n" for sort keys %h}' file
abc, 12345, 56345, 15475, 123345

def, text and nos, text and nos, text and nos, text and nos

ghi, something else, something else, something else, something else

jkl, words and numbers, words and numbers, words and numbers, words and numbers

giải pháp perl của bạn từ câu hỏi của tôi unix.stackexchange.com/questions/124181/ cũng nên hoạt động đúng không?
Ramesh

Không. OP muốn nối chuỗi dựa trên cột 1, bất kể trùng lặp hay không. Câu hỏi của bạn không muốn trùng lặp.
cuonglm

ồ được thôi. Thoạt nhìn, có vẻ như gần giống với câu hỏi của tôi. :)
Ramesh

1
Gọn gàng, +1! Điều đó không giữ trật tự mặc dù, nó chỉ tạo lại nó trong ví dụ cụ thể này, nơi các trường theo thứ tự bảng chữ cái.
terdon

Chỉ để cười, tôi đã viết gần như chính xác cách tiếp cận trước khi đọc câu trả lời của bạn: perl -F, -lane 'next unless /./;push @{$k{$F[0]}}, ",@F[1..$#F]"; END{print "$_@{$k{$_}}" foreach keys(%k)}' file:) Những bộ óc vĩ đại nghĩ giống nhau!
terdon

1

Ồ, đó là một điều dễ dàng. Đây là một phiên bản đơn giản giữ thứ tự các phím khi chúng xuất hiện trong tệp:

$ awk -F, '
    /.+/{
        if (!($1 in Val)) { Key[++i] = $1; }
        Val[$1] = Val[$1] "," $2; 
    }
    END{
        for (j = 1; j <= i; j++) {
            printf("%s %s\n%s", Key[j], Val[Key[j]], (j == i) ? "" : "\n");       
        }                                    
    }' file.txt

Đầu ra sẽ trông như thế này:

abc, 12345, 56345, 15475, 123345

def, text and nos, text and nos, text and nos, text and nos

ghi, something else, something else, something else, something else

jkl, words and numbers, words and numbers, words and numbers, words and numbers

Nếu bạn không phiền khi có thêm một dòng trống ở cuối, chỉ cần thay thế printfdòng bằngprintf("%s %s\n\n", Key[j], Val[Key[j]]);

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.