Sắp xếp duy nhất: Chuyển hướng đầu ra sang cùng một tệp


14

Có cách nào ngắn để lưu đầu ra của ống vào cùng một tệp mà nó đã xử lý không. Ví dụ, đây là những gì tôi đang làm

$ cat filename | sort | uniq > result
$ rm -f filename
$ mv result filename

Tôi đã tự hỏi nếu có một cách để làm điều đó chỉ trong một dòng (không nối thêm các lệnh đó bằng &&)

Đây không phải là cách, nhưng để có được một ý tưởng

$ cat filename | sort | uniq > filename

2
echo $(cat filename | sort | uniq > result) > filenamehay cái gì đó Chỉ cần đi ngang qua, tôi không có thời gian để thử nó.
MrVaykadji

Câu trả lời:


18

Bạn có thể sử dụng spongetừ gói moreutils :

LC_ALL=C sort -u filename | sponge filename

Bạn cũng không cần đường ống uniq, vì khi nào sort-utùy chọn cho các dòng duy nhất khi sắp xếp.

Lưu ý rằng trên hệ thống GNU có các vị trí UTF-8 sort -uhoặc sort | uniqkhông cung cấp cho bạn các dòng duy nhất, nhưng đầu tiên từ chuỗi các dòng sắp xếp giống nhau trong ngôn ngữ hiện tại.

$ printf '%b\n' '\U2460' '\U2461' | LC_ALL=en_US.utf8 sort | LC_ALL=en_US.utf8 uniq

chỉ cho bạn . Thay đổi ngôn ngữ thành C buộc thứ tự sắp xếp dựa trên các giá trị byte:

$ export LC_ALL=C
$ printf '%b\n' '\U2460' '\U2461' | LC_ALL=C sort | LC_ALL=C uniq


12

Bạn không cần thêm bất kỳ lệnh như catuniqvà cũng không sử dụng rmlệnh và mvlệnh để loại bỏ và đổi tên filename. chỉ cần sử dụng lệnh đơn giản.

sort -u filename -o filename


 -u, --unique
        with -c, check for strict ordering; without -c, output only  the
        first of an equal run

 -o, --output=FILE
        write result to FILE instead of standard output

Làm thế nào nó hoạt động?

sortlệnh sắp xếp tên tệp của bạn và với -utùy chọn, loại bỏ các dòng trùng lặp khỏi nó. sau đó với -otùy chọn ghi đầu ra vào cùng một tệp với phương thức in Place.


3
Nếu hệ thống gặp sự cố khi sortđang chạy, bạn sẽ mất tập tin gốc.
cuonglm

@Gnouc Vậy, đây là kết thúc của sự xui xẻo !! : '(
αғsнι

1
cảm ơn! trong ví dụ này, đặc biệt là với các ứng dụng, tôi nên làm điều đó. Tuy nhiên tôi đã suy nghĩ về một trường hợp chung. @Gnouc, haha ​​không có cách nào để nghĩ rằng nếu điều đó không xảy ra với bạn, phải không?
whitenoisedb

3

Ví dụ được đề xuất của bạn (bên dưới) không hoạt động vì bạn thực sự đang đọc và ghi vào cùng một tệp.

$ cat filename | sort | uniq > filename

Ý tưởng với một đường ống hoặc chuyển hướng là lệnh ở phía bên trái và bên phải của mỗi đường ống hoặc chuyển hướng chạy đồng thời, song song. Lệnh bên phải xử lý thông tin khi nó được chuyển cho nó từ lệnh bên trái, trong khi lệnh bên trái vẫn đang chạy.

Để kịch bản của bạn hoạt động, lệnh đọc từ tệp sẽ cần phải hoàn thành trước khi lệnh ghi vào tệp bắt đầu. Để làm việc này, trước tiên bạn cần chuyển hướng đầu ra vào một vị trí tạm thời, sau đó sau khi hoàn tất, hãy gửi nó từ vị trí tạm thời trở lại tệp.

Cách tốt hơn để làm điều này về cơ bản giống như trong ví dụ trước đây của bạn, khi bạn chuyển hướng đến một tệp tạm thời sau đó đổi tên tệp đó trở lại ban đầu (ngoại trừ việc bạn không cần xóa tệp trước, vì di chuyển sẽ xóa mọi mục tiêu hiện có) .

$ cat filename | sort | uniq > result
$ mv -f result filename

Bạn cũng có thể lưu nó vào một biến chuỗi, ngoại trừ chỉ hoạt động khi dữ liệu đủ nhỏ để phù hợp với bộ nhớ cùng một lúc.


Khi ai đó đưa ra một chỉnh sửa được đề xuất, bạn có thể thay đổi cat filename | sortthành sort filename- catkhông cần thiết ở đây.
thomasrutter

Ví dụ của tôi dưới đây không phải là cách để làm điều đó. Cảm ơn đã làm rõ. catcó thể không cần thiết trong trường hợp này nhưng tôi đang tập trung vào phần chuyển hướng.
whitenoisedb

1
Tôi đã giải thích lý do tại sao ví dụ dưới đây của bạn sẽ không hoạt động. Tôi biết rằng bạn biết nó không hoạt động.
thomasrutter

Cảm ơn đã làm rõ! Trong thực tế, tôi đã không biết những gì đang thực sự xảy ra.
whitenoisedb

2

Bạn có thể sử dụng teelệnh:

sort -u filename | tee filename > /dev/null

Các teelệnh đọc từ đầu vào tiêu chuẩn và ghi vào đầu ra tiêu chuẩn tập tin.


2
Điều này không làm việc cho tôi.
pjvandehaar

3
Điều này không hoạt động Askubfox.com/a/752451
Steven Penny

Điều này không làm việc cho tôi. ví dụ: để di chuyển một dòng xuống dưới cùng của tệp: (cat ~/file | grep -v 3662 ; printentry 3662) | tee ~/file > /dev/nullhoạt động. Giống như bài viết gốc, điều này không hoạt động nếu bạn > ~/filekhông có tee. Tee có vẻ tương tự ở đây sort -o file, ghi vào tệp được đặt tên mà không tiếp tục cùng một đường ống.
Joshua Goldberg

Chờ đã, xin lỗi! Tôi đã thấy theo kinh nghiệm điều này sẽ mất dữ liệu một cách khó lường như được giải thích trong liên kết từ @Steven. Tạo một tệp có các số 1..9 trên 9 dòng. Việc sau đây sẽ hoạt động nhiều lần và sau đó thỉnh thoảng xóa tất cả dữ liệu khỏi tệp: (cat x | grep -v 7 ; echo 7) | tee x > /dev/null; cat x Tôi đề xuất một tệp tạm thời và mvhoặc có lẽ là giải pháp từ liên kết của @ Steven.
Joshua Goldberg

@JoshuaGoldberg bạn đã thấy câu trả lời của tôi trên trang này chưa?
Steven Penny

0

Bạn có thể sử dụng Vim trong chế độ Ex:

ex -sc 'sort u|x' filename
  1. sort u sắp xếp độc đáo

  2. x viết nếu thay đổi đã được thực hiện (họ có) và thoát

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.