Sắp xếp có hỗ trợ sắp xếp một tệp tại chỗ, như `sed --in-place` không?


80

Tôi bị mù hay không có lựa chọn nào như --in-placecho sort?

Để lưu kết quả vào tệp đầu vào, sed sử dụng -i( --in-place).

Chuyển hướng đầu ra của sorttệp đầu vào

sort < f > f

kết quả là làm cho nó trống rỗng. Nếu không có --in-placetùy chọn - có thể có một số mẹo làm thế nào để làm điều này một cách tiện dụng ?

(Điều duy nhất khiến tôi suy nghĩ:

sort < f > /tmp/f$$ ; cat /tmp/f$$ > f ; rm /tmp/f$$

Di chuyển không phải là lựa chọn đúng đắn, vì quyền của tập tin có thể bị thay đổi. Đó là lý do tại sao tôi ghi đè lên nội dung của tệp tạm thời mà sau đó tôi xóa.)


Ngoài ra insitu, cho phép bất kỳ lệnh nào được sử dụng tại chỗ.
sr_

@sr_, đó là một lệnh thú vị, nhưng nó không hoạt động với bất kỳ lệnh nào , chỉ có những lệnh viết không nhanh hơn họ đọc (nếu không, nó sẽ ghi đè tệp đầu vào trước khi lệnh đọc nó). Không có gì đảm bảo rằng nó sẽ làm việc với sort.
cjm

@cjm, tôi thực sự không chắc chắn, nhưng đây không phải là để xử lý trường hợp đó sao?
sr_

@sr_, tôi nghĩ bạn đúng. Tôi đọc mô tả thay vì nhìn vào nguồn. Mặc dù đối với các tệp thực sự lớn, nó có thể hết bộ nhớ cho bộ đệm và sự cố (có vẻ như nó không kiểm tra sự trở lại của NULL từ malloc).
cjm

@cjm: Ồ vâng, thực sự.
sr_

Câu trả lời:


110

sort-o, --outputtùy chọn lấy tên tệp làm đối số. Nếu nó giống với tệp đầu vào, nó ghi kết quả vào một tệp tạm thời, sau đó ghi đè lên tệp đầu vào ban đầu (chính xác giống như những gì sed -ilàm).

Từ GNU sorttrang thông tin:

`-o OUTPUT-FILE'
`--output=OUTPUT-FILE'
      Write output to OUTPUT-FILE instead of standard output.  Normally,
      `sort' reads all input before opening OUTPUT-FILE, so you can
      safely sort a file in place by using commands like `sort -o F F'
      and `cat F | sort -o F'.  However, `sort' with `--merge' (`-m')
      can open the output file before reading all input, so a command
      like `cat F | sort -m -o F - G' is not safe as `sort' might start
      writing `F' before `cat' is done reading it.

      On newer systems, `-o' cannot appear after an input file if
      `POSIXLY_CORRECT' is set, e.g., `sort F -o F'.  Portable scripts
      should specify `-o OUTPUT-FILE' before any input files.

và từ Thông số kỹ thuật cơ sở nhóm mở Vấn đề 7 :

-o  output
    Specify the name of an output file to be used instead of the standard 
    output. This file can be the same as one of the input files.

Chính xác ! Nó hoạt động! Tôi không thể thấy bất kỳ manh mối nào về nó man sort- đó có phải là tính năng không có giấy tờ? Có chuẩn và di động không?
Grzegorz Wierzowiecki

@GrzegorzWierzowiecki: xem cập nhật.
enzotib

Câu trả lời hay :).
Grzegorz Wierzowiecki

1
Tóm lại: sort -o <filename> <filename>sẽ sắp xếp một cách an toàn một tập tin tại chỗ.
phyatt

11

Bạn có thể sử dụng spongechức năng, đầu tiên là ngâm nó stdinvà sau đó ghi nó vào một tệp, như:

sort < f | sponge f

Nhược điểm của spongenó là sẽ lưu trữ đầu ra tạm thời trong bộ nhớ, điều này có thể gây ra vấn đề cho các tệp lớn. Nếu không, bạn phải ghi nó vào một tập tin trước và sau đó ghi đè lên tập tin gốc.

Tuy nhiên, như được chỉ ra bởi các câu trả lời khác, nói chung, sửa đổi tại chỗ nói chung không phải là một ý tưởng hay, vì ở giữa một quá trình (ví dụ: spongemột), máy có thể bị sập và sau đó bạn có thể mất cả tệp gốc và tệp mới. Trước tiên, bạn nên viết nó vào một tệp khác và sau đó sử dụng một mvhướng dẫn nguyên tử (di chuyển).


7

Thật nguy hiểm khi ghi đè tệp đầu vào bằng tệp đầu ra, bởi vì nếu chương trình hoặc hệ thống gặp sự cố trong khi tệp đang được ghi, bạn đã mất cả hai.

Một vài chương trình (chủ yếu là các phiên bản GNU) có tùy chọn tại chỗ (ví dụ: -itrên perl và GNU sed; -otrên GNU sort). Họ làm việc bằng cách đưa dữ liệu vào một tệp tạm thời và sau đó di chuyển nó vào vị trí. Đối với chương trình mà không có tùy chọn như vậy, Colin Watson của spongetiện ích (bao gồm trong moreutils Joey Hess của ) hiện công việc một cách an toàn đối với bất kỳ chương trình (ví dụ: Tôi có thể làm cut? Thay đổi một tập tin tại chỗ ; Làm thế nào tôi có thể làm cho iconv thay thế các tập tin đầu vào với các chuyển đổi đầu ra? ).

Chỉ trong những trường hợp hiếm hoi mà bạn không thể tạo lại tệp gốc với cùng quyền thì tôi mới khuyên bạn nên ghi đè tệp tại chỗ. Trong trường hợp này, tốt hơn bạn nên lưu đầu vào ban đầu ở đâu đó. Và sau đó bạn có thể chỉ cần xử lý bản sao của đầu vào và gửi nó vào tệp gốc.

cp -p f ~/f.backup
sort <~/f.backup >|f
rm ~/f.backup # optional

1
sort -okhông phải là GNU cụ thể và được thiết kế đặc biệt để xác định vị trí của tệp. sortkhông thể bắt đầu ghi đầu ra của nó trước khi nó đọc đầy đủ các đầu vào của nó (sử dụng bộ nhớ hoặc các tệp tạm thời để lưu trữ dữ liệu), do đó, nó có thể ghi đè lên đầu vào của nó một cách khá tự nhiên.
Stéphane Chazelas 8/11/2015

Và thực tế, đó là một trường hợp GNU sortkhông phải là POSIX vì sort -mo file1 file1 file2nó không được bảo đảm để hoạt động trong khi truyền thống sortbiết cách khắc phục điều đó (đọc trong Unix V7 vào những năm 70).
Stéphane Chazelas

@JoelCross Odd, sort -ohoạt động với tôi với coreutils 8.25 và thuộc tính được ghi lại trong hướng dẫn sử dụng (lưu ý rằng đó chỉ là trường hợp khi sắp xếp, không phải khi hợp nhất). Nếu bạn có thể sao chép này, hãy gửi báo cáo lỗi (cho biết dòng lệnh chính xác, (các) tệp đầu vào chính xác, hệ thống nào bạn đang chạy trên đó và cách bạn có được nhị phân).
Gilles

4

Sử dụng -ohoặc thử vim-way:

$ ex -s +'%!sort' -cxa file.txt
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.