Với GNU sort
và shell printf
được tích hợp sẵn (tất cả các kiểu tương tự POSIX hiện nay ngoại trừ một số biến thể của pdksh
):
printf '%s\0' * | sort -u --files0-from=- > output
Bây giờ, một vấn đề với điều đó là bởi vì hai thành phần của đường ống đó được chạy đồng thời và độc lập, vào thời điểm bên trái mở rộng toàn *
cầu, bên phải có thể đã tạo output
tệp có thể gây ra sự cố (có thể không xảy ra -u
ở đây) như output
là cả tệp đầu vào và đầu ra, vì vậy bạn có thể muốn đầu ra đi đến thư mục khác ( > ../output
ví dụ) hoặc đảm bảo toàn cầu không khớp với tệp đầu ra.
Một cách khác để giải quyết nó trong trường hợp này là viết nó:
printf '%s\0' * | sort -u --files0-from=- -o output
Bằng cách đó, nó sort
mở ra output
để viết và (trong các thử nghiệm của tôi), nó sẽ không làm điều đó trước khi nó nhận được danh sách đầy đủ các tệp (rất lâu sau khi toàn cầu được mở rộng). Nó cũng sẽ tránh bị ghi đè output
nếu không có tệp đầu vào nào có thể đọc được.
Một cách khác để viết nó với zsh
hoặcbash
sort -u --files0-from=<(printf '%s\0' *) -o output
Đó là sử dụng thay thế quy trình (nơi <(...)
được thay thế bằng đường dẫn tệp đề cập đến đầu đọc của ống printf
đang ghi). Tính năng này xuất phát từ ksh
, nhưng ksh
nhấn mạnh vào việc mở rộng <(...)
một đối số riêng cho lệnh để bạn không thể sử dụng nó với --option=<(...)
cú pháp. Nó sẽ làm việc với cú pháp này mặc dù:
sort -u --files0-from <(printf '%s\0' *) -o output
Lưu ý rằng bạn sẽ thấy sự khác biệt so với các cách tiếp cận cung cấp đầu ra cat
cho các tệp trong trường hợp có các tệp không kết thúc bằng ký tự dòng mới:
$ printf a > a
$ printf b > b
$ printf '%s\0' a b | sort -u --files0-from=-
a
b
$ printf '%s\0' a b | xargs -r0 cat | sort -u
ab
Cũng lưu ý rằng sort
sắp xếp bằng thuật toán đối chiếu trong miền địa phương ( strcollate()
) và sort -u
báo cáo một trong từng nhóm dòng sắp xếp giống nhau theo thuật toán đó, không phải là các dòng duy nhất ở mức byte. Nếu bạn chỉ quan tâm đến các dòng là duy nhất ở mức byte và không quan tâm nhiều đến thứ tự chúng được sắp xếp, bạn có thể muốn sửa miền địa phương thành C nơi sắp xếp dựa trên các giá trị byte ( memcmp()
; điều đó có thể sẽ tăng tốc những điều đáng kể):
printf '%s\0' * | LC_ALL=C sort -u --files0-from=- -o output
sort
nó tự động cho nhiều đầu vào tập tin .. nhưng sau đósort -u *
sẽ thất bại vớiArgument list too long
như tôi cũng giả