Tôi đang tìm kiếm một lệnh để lấy từ một tệp ở định dạng này:
hello 32
hello 67
hi 2
ho 1212
ho 1390
ho 3000
Theo định dạng này (lặp lại bằng cách lấy hàng cuối cùng của một "nhóm"):
hello 67
hi 2
ho 3000
Hiện tại tôi đang sử dụng đoạn mã Python và gấu trúc:
df = pd.read_csv(self.input().path, sep='\t', names=('id', 'val'))
# how to replace this logic with shell commands?
surface = df.drop_duplicates(cols=('id'), take_last=True)
with self.output().open('w') as output:
surface.to_csv(output, sep='\t', cols=('id', 'val'))
Cập nhật: Cảm ơn câu trả lời tuyệt vời. Dưới đây là một số điểm chuẩn:
Tệp đầu vào là 246M và chứa 8583313 dòng. Đặt hàng không quan trọng. Cột đầu tiên có kích thước cố định là 9 ký tự.
Ví dụ về tệp đầu vào:
000000027 20131017023259.0 00
000000027 20131017023259.0 11
000000035 20130827104320.0 01
000000035 20130827104320.0 04
000000043 20120127083412.0 01
...
time space complexity
tac .. | sort -k1,1 -u 27.43682s O(log(n))
Python/Pandas 11.76063s O(n)
awk '{c[$1]=$0;} END{for(... 11.72060s O(n)
Vì cột đầu tiên có độ dài cố định, uniq -w
cũng có thể được sử dụng:
tac {input} | uniq -w 9 3.25484s O(1)
-w N
sẽ chỉ xem xét các N
ký tự đầu tiên . Đối với tệp cục bộ của tôi, tôi đã có 9 char ID trong cột đầu tiên, vì vậy uniq -w 9
.
uniq -w 5
nên hoạt động. Tôi nghĩ rằng câu trả lời của bạn và Mikels là tốt hơn, vì họ không đưa ra giả định về số lượng ký tự trong cột đầu tiên. Tuy nhiên, nếu đầu vào tuân theo một ràng buộc như vậy, thì uniq -w
là nhanh nhất.
tac {input} | uniq -w 9
Công việc thế nào