Sắp xếp lại các dòng tệp như các tệp khác (Unix)


2

Có một công cụ (hoặc tùy chọn cho sort) sẽ sắp xếp lại các dòng của một tệp để chúng được sắp xếp như một khóa trong một tệp khác không?

Ví dụ: tôi có một tệp dữ liệu:

T01F01475558    30
T01F022B3A17    31
T01F022EEDFD    19
T01F026E0209    19

Và một tệp khác (sắp xếp "khóa"):

T01F022EEDFD
T01F026E0209
T01F022B3A17
T01F01475558

Có cách nào để sắp xếp tệp đầu tiên sao cho trường đầu tiên theo thứ tự như tệp thứ 2 không? Mỗi khóa là duy nhất (không trùng lặp) và có một số dòng bằng nhau trong mỗi tệp.

Có một công cụ UNIX nào tôi không biết sẽ làm điều này không?

Câu trả lời:


0

Mỗi khóa là duy nhất (không trùng lặp) và có một số dòng bằng nhau trong mỗi tệp.

Giả định này rất quan trọng. Nếu nó giữ thì lệnh này sẽ thực hiện công việc (trong Bash):

paste <(nl key.file | sort -k 2 | cut -f 1) <(sort data.file) | sort -n | cut -f 2-

Rất ít công cụ sử dụng các ký tự tab làm dấu phân cách. Vì lý do này, các tab không được xuất hiện key.file( data.filemặc dù chúng có thể xảy ra ). Các mục nhập Sane key.filenên tạo thành một cột duy nhất, vì vậy nó không phải là một vấn đề.

Giải trình:

  1. nlthêm một số dòng ở phía trước của mỗi dòng key.file; điều này làm cho các phím tự di chuyển đến cột thứ hai; sort -k 2sắp xếp theo cột thứ hai, tức là theo các phím. Các phím này sau đó bị loại bỏ cut -f 1.
  2. Một sortloại khác data.file. Vì các phím ở phía trước là duy nhất, nên cách sắp xếp mặc định này tương đương với sắp xếp theo các phím duy nhất.
  3. Hai kết quả từ sort-s được hợp nhất bởi paste. Nếu không có cutdòng ví dụ đầu tiên sẽ là:

         4  T01F01475558    T01F01475558    30
    

    Tính duy nhất của các khóa và số lượng bằng nhau của chúng trong cả hai tệp là rất quan trọng. Trong thực tế, các khóa giống nhau từ cả hai sort-s gặp nhau trong cùng một dòng paste. Vì bạn không cần các khóa trùng lặp để chiếm bộ nhớ, nên lần đầu tiên cutđược sử dụng càng sớm càng tốt. Với nó, ví dụ thực tế để lại pastelà:

         4  T01F01475558    30
    
  4. Những dòng này sau đó được sắp xếp theo giá trị số của chúng. Số dòng từ nlphía trước, vì vậy thao tác này giới thiệu thứ tự mong muốn.

  5. Cuối cùng, cutloại bỏ cột đầu tiên, để lại các dòng chính xác data.file, nhưng theo thứ tự mong muốn.

Ngoài ra, bạn có thể thử điều này (được thử nghiệm trong Bash):

while IFS='' read -r ; do
   [ -n "$REPLY" ] && grep "^$REPLY " data.file
done <key.file

Lưu ý mã mong đợi một ký tự khoảng trắng sau mỗi khóa data.file.

Ưu điểm:

  • key.filecó thể chỉ định bất kỳ số lượng khóa, khóa trùng lặp, khóa không tồn tại. Trong trường hợp này, đừng nghĩ "sắp xếp", hãy nghĩ "lấy từng dòng mong muốn".
  • Bạn có thể truyền phát đầu vào (như stdin thay vì key.file, chỉ cần bỏ qua <key.file) và nhận đầu ra một cách nhanh chóng.

Nhược điểm:

  • grepsẽ diễn giải các khóa như các biểu thức thông thường, điều này có thể phản tác dụng. Có grep -Fnhưng nói chung bạn cần ^trong mô hình.
  • readlà chậm; sinh sản grepnhiều lần là chậm; mở đi mở data.filelại là chậm.
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.