Score:5

วิธีที่ดีที่สุดในการลบข้อความออกจากจุดเริ่มต้นของไฟล์ขนาดใหญ่

ธง de

ฉันมีไฟล์สำรองข้อมูล MySQL ขนาดใหญ่ (จาก mysqldump) พร้อมตารางตามลำดับตัวอักษร การคืนค่าของฉันล้มเหลว และฉันต้องการดำเนินการต่อจากจุดที่ฉันค้างไว้ด้วยตารางถัดไปในไฟล์สำรอง (ฉันได้แก้ไขปัญหาแล้ว นี่ไม่ใช่คำถามเกี่ยวกับการกู้คืน MySQL ฯลฯ)

สิ่งที่ฉันต้องการจะทำคือนำไฟล์สำรองของฉันเช่น backup.sql และตัดส่วนต้นของไฟล์ออกจนกว่าฉันจะเห็นบรรทัดนี้:

-- โครงสร้างตารางสำหรับ `mytable`

จากนั้นทุกอย่างหลังจากนั้นจะจบลงในไฟล์ผลลัพธ์ของฉัน พูด สำรองข้อมูล Secondhalf.sql. สิ่งนี้ค่อนข้างซับซ้อนเนื่องจากไฟล์ถูกบีบอัดด้วย bzip2 แต่นั่นก็ไม่ใช่เรื่องใหญ่เกินไป

ฉันคิดว่าฉันสามารถทำได้ดังนี้:

$bunzip2 -c backup.sql.bz2 | grep --text --byte-offset --only-matching -e '--Table structure for table `mytable`' -m 1

สิ่งนี้จะให้ค่าชดเชยไบต์ในไฟล์ที่ฉันต้องการตัดแต่ง จนถึง. แล้ว:

$bunzip2 -c backup.sql.bz2 | dd ข้าม = [ตัวเลขจากด้านบน] | bzip2 -c > สำรองข้อมูลครึ่งหลัง sql.bz2

น่าเสียดายที่ฉันต้องเรียกใช้ bunzip2 บนไฟล์สองครั้งและอ่านผ่านไบต์เหล่านั้นทั้งหมดสองครั้ง

มีวิธีทำทั้งหมดในครั้งเดียวหรือไม่?

ฉันไม่แน่ใจว่า sed-fu ของฉันแข็งแกร่งพอที่จะทำนิพจน์ "ลบทุกบรรทัดจนกว่าจะมีนิพจน์ปกติ จากนั้นปล่อยให้ไฟล์ที่เหลือผ่าน"

นี่คือบน Debian Linux ดังนั้นฉันจึงมีเครื่องมือ GNU

eg flag
หากบรรทัดสามารถมีความยาวได้ตามอำเภอใจ คุณจะรู้ได้อย่างไรว่า grep จะสามารถค้นหาสตริงเป้าหมาย `---Table structure` ได้ นอกจากนี้ สตริงเป้าหมายอยู่ที่จุดเริ่มต้นของบรรทัดเสมอหรือไม่ ถ้าเป็นเช่นนั้น โปรแกรมแบบกำหนดเองควรทำงานได้แม้กับบรรทัดที่ยาวโดยพลการ (N = ความยาวของสตริงเป้าหมายคงที่): อ่านบัฟเฟอร์ ค้นหาการขึ้นบรรทัดใหม่แต่ละบรรทัด ตรวจหา N ตัวอักษรในบัฟเฟอร์ที่อยู่หลังบรรทัดใหม่ (มิฉะนั้น ให้เลื่อนบรรทัดใหม่ไปที่จุดเริ่มต้นของ บัฟเฟอร์, เติมส่วนที่เหลือของบัฟเฟอร์), ตรวจสอบสตริงเป้าหมายหลังจากขึ้นบรรทัดใหม่, ข้ามไปยังบรรทัดใหม่ถัดไปหากไม่พบ ไม่ต้องมี KMP
eg flag
หากข้อมูลไม่ได้บีบอัดในไฟล์ปกติ (ค้นหาได้) แล้ว `grep -m1` ตามด้วย `cat` ก็จะใช้ได้
Score:8
ธง vn
bunzip2 -c สำรองข้อมูล sql.bz2 | \
  sed -n '/-- โครงสร้างตารางสำหรับ `mytable`/,$p'

คำอธิบาย:

-n ระงับการพิมพ์พื้นที่รูปแบบอัตโนมัติ

การสร้างช่วงที่อยู่: เริ่มด้วย regex

/-- โครงสร้างตารางสำหรับ `mytable`/

ปิดท้ายด้วย

$ ตรงกับบรรทัดสุดท้าย

สั่งการ

p พิมพ์ช่องว่างรูปแบบปัจจุบัน

แก้ไข: ขึ้นอยู่กับว่าคุณดัมพ์ฐานข้อมูลที่คุณมีอย่างไร มาก เส้นยาว GNU sed สามารถจัดการพวกมันได้สูงสุดตามจำนวนหน่วยความจำที่มีอยู่

de flag
แน่นอนฉันมีเส้นยาวมาก นี่เป็นระบบแบบ 64 บิต ดังนั้นในทางทฤษฎีแล้วมันอาจเต็มใจที่จะจัดสรรมากถึง 2^64 ไบต์ให้กับกระบวนการเดียว แต่หน่วยความจำกายภาพของฉันจำกัดที่ 64GiB และการสลับนั้นไม่มีที่ไหนเลยใกล้กับช่วงกิกะไบต์ ดังนั้นฉันคิดว่าพื้นที่รูปแบบทั้งหมดจะไม่พอดีกับหน่วยความจำสำหรับเส้นยาวเหล่านั้น
Score:2
ธง de

หมายเหตุ: ไม่ใช่คำตอบจริง

เนื่องจากฉันมีแรงจูงใจที่จะแก้ไขปัญหานี้ ตอนนี้ฉันไปข้างหน้าและใช้ เกรป เพื่อค้นหาออฟเซ็ตในไฟล์ที่ฉันต้องการ มันใช้งานได้ดี

วิ่ง วว น่าเสียดายที่คุณต้องตั้งค่า ไอบีเอส=1 ซึ่งโดยพื้นฐานแล้วหมายความว่าไม่มีการบัฟเฟอร์ และประสิทธิภาพก็แย่มาก ในขณะที่รอให้ dd เสร็จสิ้น ฉันใช้เวลาเขียนโปรแกรม C ที่สร้างขึ้นเองเพื่อข้ามไบต์ พอทำแล้วเห็นว่า หาง สามารถทำเพื่อฉันได้อย่างง่ายดาย:

$bunzip2 -c restore.sql.bz2 | หาง -c +[ออฟเซ็ต] | bzip2 -c > เรียกคืน trimmed.sql.bz2

ฉันพูดว่า "สิ่งนี้ไม่ตอบคำถามของฉัน" เพราะมันยังต้องมีการผ่านไฟล์สองครั้ง: หนึ่งเพื่อค้นหาค่าชดเชยของสิ่งที่ฉันกำลังมองหาและอีกอันหนึ่งเพื่อตัดแต่งไฟล์

ถ้าฉันต้องกลับไปใช้โปรแกรมที่กำหนดเอง ฉันสามารถใช้ กมธ ในช่วง "อ่านอย่างเดียว" ของโปรแกรม จากนั้นสลับไปที่ "อ่าน+เขียนทุกอย่าง" หลังจากนั้น

Score:0
ธง cn

ฉันสงสัยว่าสิ่งที่ต้องการจะทำเคล็ดลับ:

ใช้อย่างเข้มงวด
ใช้คำเตือน
ใช้คุณสมบัติ 'พูด';

ใช้ IO::Uncompress::Bunzip2 '$Bunzip2Error';

my $file = $ARGV[0] // die "ต้องการไฟล์";

$zh ของฉัน = IO::Uncompress::Bunzip2->new( $file, {
    ปิดอัตโนมัติ => 1,
    โปร่งใส => 1,
} ) หรือตาย "IO::Uncompress::Bunzip2 ล้มเหลว: $Bunzip2Error\n";

ทริกเกอร์ $ ของฉัน = undef;
ในขณะที่ ( <$zh> ) {
    สับ;
    $trigger = 1 if $_ eq '--dumping data for table `experiments`';
    พูดว่า $ทริกเกอร์;
}

โดยพื้นฐานแล้วมันจะเริ่มพิมพ์สิ่งต่าง ๆ หลังจากรูปแบบ เราสามารถไปป์โดยตรงไปยัง bzip2/gzip เช่น perl chop.pl input_sql.bz2 | bzip2 > out.sql.bz2 คุณจะต้อง libio-บีบอัด-perl บนเดเบียน

de flag
การดำเนินการนี้อาจใช้งานได้ แต่อาจใช้ไม่ได้หรือหน่วยความจำไม่เพียงพอ ขึ้นอยู่กับวิธีที่ Perl ปฏิบัติต่อบรรทัดที่ยาว ฉันเชื่อว่า `` จะลงเอยด้วยการอ่านบรรทัดเดียวในความทรงจำ และนั่นน่าจะระเบิด บางบรรทัดมีความยาวหลายสิบ GiB

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา