Xóa tiêu đề tại chỗ hiệu quả cho các tệp lớn bằng sed?


24

Các lệnh dưới đây có thể mất vài phút tùy thuộc vào kích thước tệp. Có phương pháp nào hiệu quả hơn?

sed -i 1d large_file 

Câu trả lời:


34

edThay vào đó hãy thử :

ed <<< $'1d\nwq' large_file

Nếu đó là một số lượng lớn có nghĩa là khoảng 10 triệu dòng trở lên, sử dụng tốt hơn tail. Không thể chỉnh sửa tại chỗ, nhưng hiệu suất của nó khiến điều đó không thể tha thứ:

tail -n +2 large_file > large_file.new

Chỉnh sửa để hiển thị một số khác biệt về thời gian:

( awkmã do Jaypal thêm vào để có thời gian thực hiện trên cùng một máy (CPU 2.2GHz).)

bash-4.2$ seq 1000000 > bigfile.txt # further file creations skipped

bash-4.2$ time sed -i 1d bigfile.txt
time 0m4.318s

bash-4.2$ time ed -s <<< $'1d\nwq' bigfile.txt
time 0m0.533s

bash-4.2$ time perl -pi -e 'undef$_ if$.==1' bigfile.txt
time 0m0.626s

bash-4.2$ time { tail -n +2 bigfile.txt > bigfile.new && mv -f bigfile.new bigfile.txt; }
time 0m0.034s

bash-4.2$ time { awk 'NR>1 {print}' bigfile.txt > newfile.txt && mv -f newfile.txt bigfile.txt; }
time 0m0.328s

Trong trường hợp tail, tôi muốn tính thời gian để thực hiện cả việc loại bỏ dòng đầu tiên thay thế bigfile.txtbằng bigfile.new.
rozcietrzewiacz

@rozcietrzewiacz, quan điểm của bạn là chính xác. Cảm ơn bạn. Cập nhật.
manatwork

Điều này thực sự mát mẻ! Tôi đã làm như vậy với awkvà nhận được kết quả như sau -[jaypal:~/Temp] seq 1000000 > bigfile.txt [jaypal:~/Temp] time awk 'NR>1 {print}' bigfile.txt >newfile.txt real 0m0.649s user 0m0.601s sys 0m0.033s
jaypal singh

1
@Jaypal, tôi đã thêm mã của bạn vào danh sách thay thế. Trên máy của tôi, nó thậm chí còn nhanh hơn. Thật kỳ lạ, tôi dự đoán awkhiệu suất của nó sẽ gần hơn với sed. (Lưu ý với bản thân tôi: không bao giờ mong đợi - thay vào đó hãy thử nghiệm.)
manatwork

Đây là giải pháp tốt nhất trong trường hợp của tôi: tail -n +2 bigfile.txt > bigfile.new && mv -f bigfile.new bigfile.txt;Tôi đang sử dụng một tệp duy nhất có khóa để theo dõi danh sách tác vụ duy nhất được sử dụng bởi nhiều quy trình. Tôi bắt đầu với những gì người đăng ban đầu sử dụng : sed -i 1d large_file . Điều đó đã khiến tập tin bị khóa trong 1-2 giây. Các tail/mvkết hợp hoàn gần như ngay lập tức. Cảm ơn bạn!
Chris Adams

6

Không có cách nào để loại bỏ hiệu quả mọi thứ từ đầu tập tin. Xóa dữ liệu từ đầu yêu cầu viết lại toàn bộ tập tin.

Việc cắt bớt từ cuối tệp có thể rất nhanh chóng (HĐH chỉ phải điều chỉnh thông tin kích thước tệp, có thể xóa các khối không sử dụng bây giờ). Điều này thường không thể thực hiện được khi bạn cố gắng xóa khỏi phần đầu của tệp.

Về mặt lý thuyết có thể là "nhanh" nếu bạn loại bỏ toàn bộ khối / mức chính xác, nhưng không có lệnh gọi hệ thống nào cho điều đó, vì vậy bạn phải dựa vào ngữ nghĩa dành riêng cho hệ thống tệp (nếu có). (Hoặc có một số hình thức bù trong khối / phạm vi đầu tiên để đánh dấu sự bắt đầu thực sự của tệp, tôi đoán vậy. Chưa bao giờ nghe về điều đó.)


Nếu tệp rất lớn, chi phí I / O có thể lớn hơn (có thể nhiều) so với chi phí CPU cần thiết để xử lý cuối dòng.
Mat

Bạn đúng rồi. Tuy nhiên, có thể có sự khác biệt trong cách các công cụ truy cập nội dung tệp. Tốt nhất là không xử lý từng dòng khi không cần thiết hoặc ít nhất là không đọc từng dòng khi không cần thiết.
manatwork

2
Tôi ngạc nhiên về sự khác biệt quá lớn trong kết quả của bạn và có thể sao chép nó với kích thước tệp ở đây. Lợi ích dường như giảm khi kích thước tệp tăng lên (đã thử với seq 10M, 15 giây cho sed, 5s cho ed). Mẹo hay nào (+1).
Mat

Bắt đầu với phiên bản 3.15, Linux hiện có API để thu gọn các phần của tệp trên một số hệ thống tệp dựa trên mức độ nào đó, nhưng ít nhất là đối với ext4 chỉ có thể được thực hiện trên các khối đầy đủ (thường là 4k).
Stéphane Chazelas

Ngay cả khi chỉnh sửa yêu cầu viết lại toàn bộ tệp, đôi khi rất tiện dụng để có các công cụ dòng lệnh để chỉnh sửa hiệu quả. Trong trường hợp của tôi, điều này hữu ích khi tôi phải xóa dòng đầu tiên của tệp lớn hơn tổng RAM hệ thống của tôi.
Jason

3

Phương pháp hiệu quả nhất, đừng làm điều đó! Nếu bạn làm, trong mọi trường hợp, bạn cần gấp đôi dung lượng 'lớn' trên đĩa và bạn lãng phí IOs.

Nếu bạn bị mắc kẹt với một tệp lớn mà bạn muốn đọc mà không có dòng thứ 1, hãy đợi cho đến khi bạn cần đọc nó để xóa dòng thứ nhất. Nếu bạn cần gửi tệp từ stdin đến một chương trình, hãy sử dụng đuôi để thực hiện:

tail -n +2 | your_program

Khi bạn cần đọc tệp, bạn có thể nhân cơ hội xóa dòng thứ 1, nhưng chỉ khi bạn có đủ dung lượng cần thiết trên đĩa:

tail -n +2 | tee large_file2 | your_program

Nếu bạn không thể đọc từ stdin, hãy sử dụng fifo:

mkfifo large_file_wo_1st_line
tail -n +2 large_file > large_file_wo_1st_line&
your_program -i large_file_wo_1st_line

thậm chí tốt hơn nếu bạn đang sử dụng bash, hãy tận dụng thay thế quy trình:

your_program -i <(tail -n +2 large_file)

Nếu bạn cần tìm kiếm trong tệp, tôi không thấy giải pháp nào tốt hơn là không bị kẹt với tệp ở vị trí đầu tiên. Nếu tệp này được tạo bởi thiết bị xuất chuẩn:

large_file_generator | tail -n +2 > large_file

Khác, luôn luôn có giải pháp thay thế fifo hoặc quá trình:

mkfifo large_file_with_1st_file
large_file_generator -o large_file_with_1st_file&
tail -n +2 large_file_with_1st_file > large_file_wo_1st_file

large_file_generator -o >(tail -n 2+ > large_file_wo_1st_file)

1

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

ex -sc '1d|x' large_file
  1. 1 chọn dòng đầu tiên

  2. d xóa bỏ

  3. x lưu và đóng


0

Đây chỉ là lý thuyết, nhưng ...

Một hệ thống tệp tùy chỉnh (được triển khai bằng FUSE hoặc một cơ chế tương tự) có thể hiển thị một thư mục có nội dung giống hệt như một thư mục đã tồn tại ở một nơi khác, nhưng với các tệp bị cắt bớt như bạn muốn. Hệ thống tập tin sẽ dịch tất cả các tập tin offset. Sau đó, bạn sẽ không phải viết lại một tập tin tốn thời gian.

Nhưng cho rằng ý tưởng này rất không tầm thường, trừ khi bạn có hàng chục terabyte các tệp như vậy, việc thực hiện hệ thống tệp như vậy sẽ quá tốn kém / tốn thời gian.

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.