Hợp nhất các tệp bằng một cột chung


8

Tôi có hai tệp trong đó tôi muốn tạo một tệp thứ ba chứa tất cả thông tin.

tập tin 1:

a 111 
b 222 
c 333 
d 666 
e 777 

tập 2:

111 x1  
222 x2
333 x3
444 x4 
555 x5 
666 x6 
777 x7 
888 x8

Tôi muốn kết hợp chúng như sau:

111  x1  a
222  x2  b
333  x3  c
444  x4  0
555  x5  0
666  x6  d
777  x7  e
888  x8  0

Ghi chú:

Cột thứ hai của tệp 1 là tập hợp con của cột đầu tiên của tệp 2

Câu trả lời:


7

Các joinlệnh thực hiện hầu hết những gì bạn cần, nếu các tập tin đều được sắp xếp như trong mẫu của bạn:

join -12 -a2 file1 file2 -o2.1,2.2,1.1

Bạn chỉ cần thêm các số 0 vào các dòng không khớp. Bạn có thể sử dụng công -etắc cho điều đó:

join -12 -a2 file1 file2  -o2.1,2.2,1.1 -e0

nếu bạn thêm -e0không cần perl :)
LilloX

@LilloX: Đúng, cảm ơn. Tôi đã thử nhưng thất bại (lỗi đánh máy).
choroba

13

Sử dụng tham gia:

join -1 1 -2 2 -a1 -e0 -o'0,1.2,2.1' file2 file1

Lệnh tham gia nối các dòng của hai tệp chia sẻ một trường dữ liệu chung. Trong trường hợp này: Tham gia tệp2 và tệp1 bằng cách sử dụng trường 1 ( -1 1) của tệp2 và trường 2 ( -2 2) của tệp1.

Đầu ra sẽ là: "trường đã tham gia, trường 2 của tệp2, trường 1 của tệp1" ( -o'0,1.2,2.1'), nếu có trường bị thiếu, đặt 0 ( -e0)

Nếu một trong hai tệp có nhiều bản ghi thì hãy thêm chúng (trong trường hợp này là tệp2) ( -a1)

Vui lòng tham khảo trang chủ của lệnh tham gia


Tốt Bạn có thể thêm một chút giải thích?
Lety

Chắc chắn, đã cập nhật :)
LilloX

5

Một chút awkma thuật:

awk 'FNR==NR{a[$2]=$1;next}{if(a[$1]==""){a[$1]=0}; \
    printf "%s%s%s%s%s\n",$1,FS,$2,FS,a[$1]}' \
    file1 file2

hoặc là

awk 'FNR==NR{a[$2]=$1;next}{if(a[$1]==""){a[$1]=0};
    print $1,$2,a[$1]}' file1 file2

Đầu ra

111 x1 a
222 x2 b
333 x3 c
444 x4 0
555 x5 0
666 x6 d
777 x7 e
888 x8 0

Giải trình

  • FNR==NR{a[$2]=$1;next}

    Chạy qua file1( FNR==NR) và tạo cấu trúc khóa-giá trị. Khóa là cột thứ hai ( $2) của file1, giá trị là cột đầu tiên ( $1) củafile1

  • {if(a[$1]==""){a[$1]=0};print $1,$2,a[$1]}

    Chạy qua file2

    • if(a[$1]==""){a[$1]=0}

      Nếu khóa trong cột đầu tiên ( $1) trong file2không tồn tại file1, chúng ta cần một0

    • print $1,$2,a[$1]

      In (sử dụng print) cột đầu tiên và cột thứ hai file2và giá trị của cấu trúc khóa-giá trị với khóa của cột đầu tiên ( $1) củafile2

      hoặc là

    • printf "%s%s%s%s%s\n",$1,FS,$2,FS,a[$1]}'

      In (sử dụng printf) cột đầu tiên và cột thứ hai file2và giá trị của cấu trúc khóa-giá trị với khóa của cột đầu tiên ( $1) của file2.

      • FS là dấu phân cách giữa các cột, được lấy từ tệp đầu vào

      • "%s%s%s%s%s\n"

        là định dạng cho đầu ra

        • %s - Chuỗi

        • \n - Dòng mới


Bạn có thể giải thích mã?
gforce89

Chắc chắn, câu trả lời cập nhật.
AB

1

Sử dụng q :

$ q "select f2.c1, f2.c2, ifnull(f1.c1,0) from file_2.txt f2 LEFT JOIN file_1.txt f1 on f1.c2 = f2.c1 "
111 x1 a
222 x2 b
333 x3 c
444 x4 0
555 x5 0
666 x6 d
777 x7 e
888 x8 0

Nó có thể dễ đọc hơn theo cách này đôi khi.


1
Đối với bất kỳ ai thắc mắc, qlà trong gói python3-q-text-as-data(Python 3) và trong gói python-q-text-as-data(Python 2).
kos

Cảm ơn, nhưng tôi có thể nhận qgói này ở đâu? Tôi dường như không thể cài đặt python-q-text-as-datahoặc python3-q-text-as-data. "E: Không thể định vị gói python3-q-text-as-data". Hệ thống của tôi đã có được cài đặt python, python2.7, python3, và python3.4.
Paddy Landau

Có thể gói quá mới và không có sẵn trong bản phát hành phân phối của bạn. Bạn có thể sao chép nó Github: github.com/harelba/q
Vi.
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.