Điểm:5

Cách tốt nhất để xóa văn bản khỏi phần đầu của một tệp lớn

lá cờ de

Tôi có một tệp sao lưu MySQL khổng lồ (từ mysqldump) với các bảng theo thứ tự bảng chữ cái. Quá trình khôi phục của tôi không thành công và tôi muốn tiếp tục từ nơi tôi đã dừng lại với bảng tiếp theo trong tệp sao lưu. (Tôi đã khắc phục sự cố, đây thực sự không phải là câu hỏi về khôi phục MySQL, v.v.)

Điều tôi muốn làm là lấy tệp sao lưu của mình, ví dụ: sao lưu.sql và cắt bỏ phần đầu của tệp cho đến khi tôi thấy dòng này:

-- Cấu trúc bảng cho `mytable`

Sau đó, mọi thứ sau đó sẽ kết thúc trong tệp kết quả của tôi, giả sử backup-secondhalf.sql. Điều này hơi phức tạp bởi thực tế là tệp được nén bzip2, nhưng đó không phải là vấn đề quá lớn.

Tôi nghĩ rằng tôi có thể làm điều đó như thế này:

$ bunzip2 -c backup.sql.bz2 | grep --text --byte-offset --only-matching -e '--Cấu trúc bảng cho bảng `mytable`' -m 1

Điều này sẽ cung cấp cho tôi phần bù byte trong tệp mà tôi muốn cắt lên đến. Sau đó:

$ bunzip2 -c backup.sql.bz2 | dd bỏ qua=[số từ trên] | bzip2 -c > backup-secondhalf.sql.bz2

Thật không may, điều này yêu cầu tôi chạy bunzip2 trên tệp hai lần và đọc qua tất cả các byte đó hai lần.

Có cách nào để làm điều này tất cả cùng một lúc?

Tôi không chắc sed-fu của mình đủ mạnh để thực hiện biểu thức "xóa tất cả các dòng cho đến khi biểu thức chính quy, sau đó để phần còn lại của tệp thông qua".

Đây là trên Debian Linux, vì vậy tôi có sẵn các công cụ GNU.

lá cờ eg
Nếu các dòng có thể có độ dài tùy ý, làm sao bạn biết rằng grep sẽ có thể định vị chuỗi mục tiêu `--Table structure`? Ngoài ra, chuỗi mục tiêu có luôn ở đầu dòng không? Nếu vậy, thì một chương trình tùy chỉnh sẽ hoạt động ngay cả đối với các dòng dài tùy ý (N = độ dài của chuỗi mục tiêu cố định): đọc bộ đệm, định vị lần lượt từng dòng mới, kiểm tra N ký tự trong bộ đệm qua dòng mới (nếu không chuyển dòng mới về đầu đệm, điền phần còn lại của bộ đệm), kiểm tra chuỗi đích sau dòng mới, bỏ qua dòng mới tiếp theo nếu không tìm thấy. Không cần KMP.
lá cờ eg
Nếu dữ liệu đã được giải nén trong một tệp thông thường (có thể tìm kiếm), thì `grep -m1` theo sau bởi `cat` sẽ hoạt động.
Điểm:8
lá cờ vn
bunzip2 -c backup.sql.bz2 | \
  sed -n '/-- Cấu trúc bảng cho `mytable`/,$p'

Giải trình:

-n chặn tự động in không gian mẫu

Xây dựng dải địa chỉ: Bắt đầu với biểu thức chính quy

// Cấu trúc bảng cho `mytable`/

Kết thúc với

$ Khớp dòng cuối cùng.

Chỉ huy

p In không gian mẫu hiện tại.

Chỉnh sửa: tùy thuộc vào cách bạn kết xuất cơ sở dữ liệu mà bạn có thể có rất xếp hàng dài. GNU sed có thể xử lý chúng trong phạm vi bộ nhớ khả dụng.

lá cờ de
Thật vậy, tôi có những dòng rất dài. Đây là hệ thống 64 bit, vì vậy về mặt lý thuyết, nó có thể sẵn sàng phân bổ tới 2^64 byte cho một quy trình. Nhưng bộ nhớ vật lý của tôi bị giới hạn ở 64GiB và trao đổi không ở gần phạm vi gigabyte. Vì vậy, tôi nghĩ rằng toàn bộ không gian mẫu sẽ không phù hợp với bộ nhớ cho những dòng dài đó.
Điểm:2
lá cờ de

LƯU Ý: Không phải là một câu trả lời thực tế

Vì tôi đã có động lực để giải quyết vấn đề này hiện nay, tôi đã tiếp tục và sử dụng tiếng kêu để tìm phần bù trong tệp tôi muốn; nó hoạt động rất tốt.

Đang chạy đ tiếc là bạn phải đặt ibs=1 về cơ bản có nghĩa là không có bộ đệm và hiệu suất rất tệ. Trong khi đợi dd hoàn thành, tôi đã dành thời gian viết chương trình C được tạo tùy chỉnh của riêng mình để bỏ qua các byte. Sau khi đã làm điều đó, tôi thấy rằng đuôi có thể đã làm điều đó cho tôi một cách dễ dàng:

$ bunzip2 -c khôi phục.sql.bz2 | đuôi -c +[bù] | bzip2 -c > khôi phục-trimmed.sql.bz2

Tôi nói "điều này không trả lời câu hỏi của tôi" bởi vì nó vẫn yêu cầu hai lần chuyển qua tệp: một lần để tìm phần bù của thứ tôi đang tìm và một lần khác để cắt tệp.

Nếu tôi quay lại chương trình tùy chỉnh của mình, tôi có thể triển khai một KMP trong giai đoạn "chỉ đọc" của chương trình và sau đó chuyển sang "đọc + ghi mọi thứ" sau đó.

Điểm:0
lá cờ cn

Tôi tự hỏi nếu một cái gì đó như thế sẽ thực hiện thủ thuật:

Sử dụng nghiêm ngặt;
sử dụng cảnh báo;
sử dụng tính năng 'nói';

sử dụng IO::Uncompress::Bunzip2 '$Bunzip2Error';

my $file = $ARGV[0] // chết "cần một tập tin";

của tôi $zh = IO::Uncompress::Bunzip2->new( $file, {
    Tự động Đóng => 1,
    Trong suốt => 1,
} ) hoặc chết "IO::Uncompress::Bunzip2 fail: $Bunzip2Error\n";

$trigger của tôi = undef;
trong khi ( <$zh> ) {
    nhai;
    $trigger = 1 if $_ eq '-- Kết xuất dữ liệu cho bảng `thử nghiệm`';
    nói nếu $trigger;
}

Vì vậy, về cơ bản, nó bắt đầu in nội dung sau mẫu, người ta cũng có thể chuyển trực tiếp nó sang bzip2/gzip, như perl chop.pl input_sql.bz2 | bzip2 > out.sql.bz2 Bạn sẽ cần libio-nén-perl trên Debian.

lá cờ de
Điều này có thể hoạt động, nhưng có thể không hoạt động hoặc hết bộ nhớ, tùy thuộc vào cách Perl xử lý các dòng dài. Tôi tin rằng `` cuối cùng sẽ đọc toàn bộ một dòng vào bộ nhớ và điều đó có thể sẽ nổ tung. Một số dòng này dài hàng chục GiB.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.