Làm thế nào đến sed là rất nhanh?


7

Tôi nghĩ về câu hỏi này có phù hợp với SE hay không, tôi hy vọng bạn đồng ý.

Cách đây một thời gian, tôi đã hỏi SE về cách tìm văn bản trong tệp và chỉ để lại tệp có các dòng phù hợp có chứa văn bản mà tôi đang tìm kiếm. Câu hỏi đặt ra ở đây: Làm thế nào để tìm văn bản trong tệp và chỉ giữ các dòng khớp tương ứng bằng thiết bị đầu cuối trên OS X?

Trong khi câu trả lời hoạt động hoàn hảo, bây giờ tôi tự hỏi, làm thế nào đến sedquá nhanh? Trong trường hợp sử dụng của tôi, tôi có khá nhiều tệp với tổng kích thước khoảng 30 Gb. Các sedlệnh ran trong khoảng 12 giây mà tôi sẽ không bao giờ tin (làm việc với một HDD bình thường). Trong vòng 12 giây, lệnh đọc qua 30 Gb văn bản, cắt bớt từng tệp để chỉ giữ các dòng tương ứng mà tôi đang lọc. Cái này hoạt động ra sao? (hoặc: phép thuật này là gì?)

Lệnh thực tế là:

find . -type f -exec sed -i'' '/\B\/foobar\b/!d' {} \;

Lệnh nào bạn thực sự chạy?
cuonglm

find . -type f -exec sed -i'' '/\B\/foobar\b/!d' {} \;
Alex

1
Đây có vẻ như là một câu hỏi khá chung chung. Bạn đang tìm kiếm loại câu trả lời nào? sed được viết bằng C, và có lẽ được tối ưu hóa cho tốc độ.
Faheem Mitha

Đối với một câu trả lời chung chung :-) nhưng có thể sâu sắc hơn, một số khía cạnh kỹ thuật, nó làm gì mà nó lại nhanh đến vậy? Nếu có nơi nào tốt hơn để hỏi điều này, xin hãy tư vấn cho tôi như vậy
Alex

Câu trả lời:


2

Câu trả lời có khả năng là:

  1. Tệp 30Gb không bị phân mảnh (hoặc có rất ít phân mảnh): tất cả các ổ đĩa cứng hoạt động tốt hơn nhiều với truy cập tuần tự (bao gồm SSD) vì chúng có thể lưu trữ các khối lớn của tệp. Điều này cho phép họ tiếp cận hiệu suất tối đa của họ. Truy cập tuần tự sẽ giúp với tất cả các cấp bộ nhớ cache.
  2. sedlà một biên tập viên dòng; nó chỉ xử lý một dòng tại một thời điểm. Điều này có nghĩa là dấu chân bộ nhớ của nó là rất nhỏ. Không giống như một trình soạn thảo văn bản như emacshoặc vim, nó không cần phải duy trì toàn bộ bản sao của tập tin trong bộ nhớ.
  3. Bạn đang chỉnh sửa tệp tại chỗ (với -i) (như được thể hiện bởi @Ramesh và cũng được nêu trên trang wikipedia ) tạo một tệp tạm thời sau đó trở thành tệp cũ.

Tất cả điều này có nghĩa sedlà có thể thực hiện gần như tối thiểu các thao tác tệp: mỗi dòng của tệp gốc được đọc một lần và chỉ các dòng được khớp được ghi.

Sự lựa chọn biểu thức chính quy của bạn cũng ảnh hưởng đến hiệu suất, đôi khi theo những cách rất tệ: mã hóa blog kinh dị .


3

Một ví dụ tuyệt vời là sedsử dụng một tệp tạm thời để thực sự lưu nội dung và sau đó thay thế tệp gốc. Ví dụ, bạn có thể thực hiện một thử nghiệm đơn giản để tìm thấy điều này.

cat test
This is a test file. 

Bây giờ, chạy ls -liđể kiểm tra số inode.

ls -li test
2368770 -rw-r--r-- 1 root root 22 Sep 12 08:46 test

Bây giờ, ban hành sedlệnh dưới đây để thêm một dòng trống.

sed -i 's/2/B/' test

Sau khi thay đổi tệp, phát hành lslệnh một lần nữa và kiểm tra số inode.

ls -li test
2368753 -rw-r--r-- 1 root root 22 Sep 12 08:48 test

Chúng ta có thể thấy rằng số inode đã thay đổi nguyên vẹn. Vì vậy, thay vì sao chép vào cùng một tệp sedsẽ tạo một tệp tạm thời mới và sao chép nội dung vào tệp tạm thời mới và sau đó xóa tệp gốc và đổi tên tệp tmp đồng bộ với tệp gốc, đó là một lý do tại sao các thao tác tệp thực sự nhanh hơn .

Trích dẫn từ trang wikipedia ,

sed là một tiện ích xử lý văn bản hướng dòng: nó đọc văn bản, từng dòng, từ một luồng đầu vào hoặc tệp, vào một bộ đệm bên trong được gọi là không gian mẫu. Mỗi dòng đọc bắt đầu một chu kỳ. Đối với không gian mẫu, sed áp dụng một hoặc nhiều thao tác đã được chỉ định thông qua tập lệnh sed. sed thực hiện một ngôn ngữ lập trình với khoảng 25 lệnh chỉ định các thao tác trên văn bản. Đối với mỗi dòng, sau khi chạy tập lệnh sed, thường xuất ra không gian mẫu (dòng đầu vào như được sửa đổi bởi tập lệnh) và bắt đầu lại chu kỳ với dòng tiếp theo.

Để hiểu thêm về không gian mẫu và giữ các khái niệm không gian của sed, bạn nên đọc câu trả lời ở đây .

Khi sed đọc một dòng tệp theo dòng, dòng hiện đang đọc được chèn vào bộ đệm mẫu (không gian mẫu). Bộ đệm mẫu giống như bộ đệm tạm thời, Scratchpad nơi lưu trữ thông tin hiện tại. Khi bạn bảo sed in, nó sẽ in bộ đệm mẫu.

Giữ bộ đệm / giữ không gian giống như một bộ lưu trữ dài hạn, để bạn có thể bắt một cái gì đó, lưu trữ và sử dụng lại sau này khi sed đang xử lý một dòng khác. Bạn không trực tiếp xử lý không gian giữ, thay vào đó, bạn cần sao chép nó hoặc nối vào không gian mẫu nếu bạn muốn làm gì đó với nó.

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.