Trích phần giữa của dòng văn bản?


17

Tôi đang viết một tập lệnh PHP để phân tích một tệp văn bản lớn để chèn cơ sở dữ liệu từ nó. Tuy nhiên, trên máy chủ của tôi, tệp quá lớn và tôi đã đạt giới hạn bộ nhớ cho PHP.

Tập tin có khoảng 16.000 dòng; Tôi muốn chia nó thành bốn tệp riêng biệt (lúc đầu) để xem liệu tôi có thể tải chúng không.

Phần đầu tiên tôi có thể nhận được với head -4000 file.txt. Phần giữa hơi phức tạp hơn - Tôi đã suy nghĩ về tailđầu ra đường ống vào head( tail -4001 file.txt | head -4000 > section2.txt), nhưng có cách nào khác / tốt hơn không?

Trên thực tế logic của tôi đã bị rối tung - đối với phần hai, tôi sẽ cần phải làm như vậy tail -12001 file.txt | head - 4000, và sau đó hạ thấp tailđối số cho các phần tiếp theo. Tôi đang bị lẫn lộn rồi! : P

Câu trả lời:


27

Nếu bạn không muốn bị làm phiền nhưng vẫn sử dụng nó tailhead, có một cách hữu ích để gọi tailbằng cách sử dụng một dòng đếm từ đầu, không phải là kết thúc:

tail -n +4001 yourfile | head -4000

... Nhưng một công cụ tự động tốt hơn được tạo ra chỉ để chia nhỏ các tập tin được gọi là ... split! Nó cũng là một phần của lõi GNU, vì vậy bất kỳ hệ thống Linux bình thường nào cũng cần có nó. Đây là cách bạn có thể sử dụng nó:

split -l 4000 yourInputFile thePrefixForOutputFiles

(Xem man splitnếu nghi ngờ.)


19

Kết hợp đầu và đuôi như bạn đã làm sẽ có hiệu quả, nhưng với điều này tôi sẽ sử dụng sed

sed -n '1,4000p' input_file # print lines 1-4000 of input_file

Điều này cho phép bạn giải quyết vấn đề của mình với chức năng shell nhanh

chunk_it(){
    step=4
    start=1
    end=$step
    for n in {1..4} ; do
        sed -n "${start},${end}p" "$1" > "$1".$start-$end
        let start+=$step
        let end+=$step
    done
}

chunk_it your_file

Bây giờ bạn có your_file.1-4000 và yuor_file.4001-8000, v.v.

Lưu ý: yêu cầu bash


3
Tôi thích cách sed.
fanchyna

Điều này không làm việc cho tôi vì sed không thoát. Nó in ra các dòng tôi muốn xuất ra, nhưng tôi phải ctrl-c ra, và kết quả là, tôi không thể chuyển hướng nó đến một tệp. Bất kỳ đề nghị để làm cho nó có thể sử dụng?
Brent212

Tìm ra! "sed -n '<start_line>, <end_line> w <output_file>' <input_file>" hoạt động với tôi.
Brent212

@ Brent212 Một tùy chọn khác cần lưu ý là bạn cũng có thể chuyển nó thành ít hơn hoặc chuyển hướng đầu ra thành một tệp.
Kyle s
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.