Làm trống nội dung của tệp văn bản


16

Tôi có một tệp văn bản trong thư mục nhà của tôi nhận dữ liệu thường xuyên thông qua một công việc định kỳ. Vì công việc cron cung cấp dữ liệu động, tôi cũng muốn đặt một công việc định kỳ để làm trống nội dung tệp (tệp vẫn phải tồn tại). Tôi không cần trợ giúp với cron, chỉ cần lệnh có thể giúp làm trống tập tin.


5
Thay thế: tail -n +1000 file.txt > file.txtnên xóa 1000 dòng và giữ các dòng mới nhất trong tệp (bạn không bao giờ biết khi nào bạn có thể cần một số bản ghi gần đây để theo dõi một cái gì đó).
Rinzwind

2
Đó thực sự là một lựa chọn tốt hơn so với việc xóa tệp vào thời gian đã lên lịch.
Bruno Pereira

1
@Rinzwind, sẽ không hoạt động vì tệp sẽ bị cắt trước khi đuôi cố đọc nó. Bạn cần chuyển hướng đến một tệp mới, và sau đó thay thế tệp gốc bằng tệp mới.
psusi

Đúng @psusi :) cần phải có thêm một chuyển hướng ở đó.
Rinzwind

Câu trả lời:


28

Cách đơn giản nhất:

> filename

Đây là một cách ít rõ ràng hơn và có thể ít người đọc hơn trong một tập lệnh shell, nhưng đó là tất cả những gì bạn cần.

Bởi vì >thực sự không phải là một lệnh thực sự (nó là bash dựng sẵn), bạn không thể sử dụng:

sudo > filename

khi bạn không có quyền trên tập tin đó. Nhưng bạn có thể sử dụng:

sudo bash -c "> filename"

Loại quyền nào cần được thay đổi vì nó cho phép bị từ chối, tôi đã thực hiện chmod 755 cho tệp hoặc tôi nên tạo một Bài đăng mới (ý tôi là câu hỏi về quyền)
sosytee

@sosytee Xem các chỉnh sửa mới của tôi.
Radu Rădeanu

1
@sosytee Tất nhiên là bạn có thể, nhưng sử dụng sudo crontab -eđể thêm công việc định kỳ cho root chứ không phải cho bạn. Hoặc thay đổi quyền của tệp thành 766 (hoặc 666), không phải là 755 : sudo chmod 766 filename. Thông tin thêm về: codex.wordpress.org/Changing_File_Permissions
Radu Rădeanu

1
truncate filenamesạch sẽ và đơn giản hơn một chút so với chuyển hướng đầu ra trống vào tệp và không gặp vấn đề với sudo.
psusi

1
@psusi truncate -s 0 filenamethực sự có thể thực hiện các mẹo. Bạn có thể thêm nó dưới dạng câu trả lời.
Radu Rădeanu

19

Có một công cụ được tạo ra cho mục đích đó:

truncate -s 0 filename

Điều này sẽ xóa nội dung nhưng nó vẫn sẽ là cùng một tệp ( inode vẫn giữ nguyên).

Điều này rất quan trọng vì một số chương trình xử lý tệp "bằng inode". Giả sử bạn "làm trống" một tệp bằng phương pháp ngây thơ là xóa và tạo lại tệp. Một số chương trình vẫn có thể xử lý tệp cũ (với nội dung cũ) ngay cả khi nó không còn hiển thị trên mỗi phương tiện thông thường như ls.

Một số liên kết đến chi tiết hơn ở cuối câu trả lời này.


Một cách khác, có thể dễ nhớ hơn:

echo -n > filename

Điều này cũng giữ cho inode tương tự.

Lưu ý rằng cả hai truncateecho -nkhông được xác định bởi POSIX .

Để sử dụng tuân thủ POSIX cat /dev/null:

cat /dev/null > filename

Một cách khác, tối nghĩa hơn và có lẽ không phải là bất khả tri:

> filename

Nếu tệp để cắt bớt cần đặc quyền gốc để ghi thì các dòng sau sẽ không hoạt động như mong đợi:

sudo echo -n > filename
sudo cat /dev/null > filename
sudo > filename

Điều này là do việc chuyển hướng được thực hiện bởi shell ngay cả trước khi sudo được thực thi. Điều đó có nghĩa là quyền truy cập ghi vào tệp được thực hiện bằng cách sử dụng các đặc quyền của người dùng chạy shell chứ không phải các đặc quyền sẽ được cấp bởi sudo.

Một cách giải quyết là trì hoãn chuyển hướng đến trình bao được thực thi bằng các đặc quyền sudo như thế này:

sudo sh -c "echo -n > filename"

Sử dụng truncatebạn không cần một cách giải quyết như vậy bởi vì việc truy cập ghi không được thực hiện bởi trình bao mà do truncatenó được thực thi bởi sudo bằng các đặc quyền sudo.

sudo truncate -s 0 filename

Để biết một số thông tin chi tiết về các chương trình giữ tệp mở ngay cả khi tệp đã bị xóa, bạn có thể đọc phần sau:


Nó nói Quyền bị từ chối, đã sử dụng tên tệp chmod 755 nhưng vẫn bị từ chối
sosytee

2
có lẽ bạn đã kích hoạt noclobber trong bash?
lesmana

Câu trả lời đầy đủ nhất cho đến nay
AbdelHady

4

Để tự động hóa điều này, bạn có thể sử dụng logrotate. Chỉ cần tạo một tệp cấu hình cho tệp bạn muốn xóa, thêm các cài đặt khác và bạn có thể tự động để trống mỗi ngày dựa trên các tiêu chí bạn chọn hàng ngày hoặc khi tệp lớn hơn, v.v.

Hãy xem ở đây về cách định cấu hình logrotate: http://linuxcommand.org/man_pages/logrotate8.html


1
Tôi ủng hộ lựa chọn này bản thân mình. Chúng tôi sử dụng "tệp> 10 Mb" -> "tar.gz để sao lưu" "tệp trống". Và các bản sao lưu sẽ bị xóa sau 900 ngày.
Rinzwind

3

echo "" > foo_filelà một cách đơn giản để làm điều đó, nó sẽ thay thế tất cả nội dung của foo_file bằng "" làm cho nó trong trường hợp này, trống rỗng.

Bạn cũng có thể sử dụng cat /dev/null > foo_file, nó sẽ đọc thiết bị null và ghi đè lên tệp của bạn mà không có gì cả.


Nó nói Quyền bị từ chối, đã sử dụng tên tệp chmod 755 nhưng vẫn bị từ chối
sosytee

Bạn có thể đọc các quyền của tập tin với người dùng bình thường của bạn xin vui lòng?
Bruno Pereira

vâng tôi có thể đọc nội dung như người dùng bình thường
sosytee
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.