ฉันมีไฟล์ไบนารีขนาดใหญ่ (หลายร้อย GB) และฉันต้องการแยกกลุ่มจากมัน ฉันรู้ว่าสตริงเลขฐานสิบหกของจุดเริ่มต้นและจุดสิ้นสุด
ฉันมีไฟล์ไบนารีขนาดใหญ่ (หลายร้อย GB) และฉันต้องการแยกกลุ่มจากมัน ฉันรู้ว่าสตริงเลขฐานสิบหกของจุดเริ่มต้นและจุดสิ้นสุด
คำตอบ:
วิธีแก้ปัญหาที่เป็นไปได้ (สมมติว่าคุณสามารถทำสำเนาไฟล์) สามารถใช้ตัวอย่างต่อไปนี้
tf
และมีความยาว 5,000 ไบต์แล้วก็
ทำสำเนาของtf
ไฟล์ใหม่blah
โดยเปลี่ยนรูปแบบเริ่มต้น
$ LC_ALL=C sed 's/'`printf "\x4f\x0f\x87\x82"`'/'`printf "AAAA"`'/' <tf > blah
ตอนนี้หาตำแหน่งที่tf
และblah
แตกต่างกัน ( note - sed เขียนไบต์พิเศษที่มีการขึ้นบรรทัดใหม่ในตอนท้ายของไฟล์ที่แก้ไขดังนั้นเราจึงเปรียบเทียบกับความยาวของไฟล์ต้นฉบับดังนั้นไฟล์tf
ที่สร้างblah
ควรมีความยาวหนึ่งไบต์ )
$ cmp -n 5000 -b tf blah
สิ่งนี้จะให้อ็อฟเซ็ตไบต์, bs, ซึ่งไฟล์ต่างกันเช่น,
tf blah differ: byte 4337, line 10 is 117 O 101 A
ตอนนี้ทำแบบเดียวกันกับตอนจบ
$ LC_ALL=C sed 's/'`printf "\xfb\x8c\xe2\xa0"`'/'`printf "AAAA"`'/' < tf > blah2
$ cmp -n 5000 -b tf blah2
tf blah2 differ: byte 4433, line 10 is 373 ? 101 A
ตอนนี้ใช้dd
เพื่อดึงส่วนที่น่าสนใจ
dd if=tf skip=4336 bs=1 count=100 > fbit
หมายเหตุพิเศษบางประการ:
sed บางรุ่นรองรับ-b
ตัวเลือกที่ใช้กับไฟล์อินพุตเป็นไบนารี รุ่นอื่นมี-z
ตัวเลือกที่คั่นบรรทัดด้วยอักขระ NUL ไม่สามารถทดสอบรูปแบบการจับคู่ที่มีบรรทัดใหม่หรือแยกข้ามบรรทัดใหม่ได้
count=100
จะขึ้นอยู่กับความยาวของรูปแบบการจับคู่และไม่ว่ารูปแบบการจับคู่ที่จะรวมอยู่ในสารสกัด (ที่ไม่ชัดเจนในคำถาม) สูตรทั่วไปคือนับ = (ตอนจบ offset) - (เริ่ม offset) + (ขนาดของรูปแบบการสิ้นสุด) ชิ้นส่วนสำหรับตัวอย่างเฉพาะคือ 4433-4337 + 1 ซึ่งให้ 97 ไบต์ นั่นคือจากจุดเริ่มต้นของรูปแบบเริ่มต้นจนถึงและรวมถึงไบต์แรกของรูปแบบสิ้นสุด เพิ่ม 3 ไบต์พิเศษเพื่อให้ 100 ในตัวอย่างนี้เนื่องจากรูปแบบสุดท้ายมีสี่ไบต์และตัวอย่างรวมถึงรูปแบบสุดท้าย หากไม่ต้องการรูปแบบสุดท้ายก็count=96
จะเป็นค่า
วิธีการที่แข็งแกร่งสำหรับบรรทัดใหม่และการใช้คำสั่ง hexdump เป็นไปได้ ฉันยังไม่ได้ทดสอบวิธีการนั้นอย่างเต็มที่ โดยพื้นฐานแล้วจะใช้ hexdump กับ sed, grep และ tr เล็กน้อยเพื่อแปลงไฟล์ไบนารีดั้งเดิมเป็น hex ในรูปแบบ ascii จากนั้นกระบวนการเดียวกันสามารถนำไปใช้ได้ แต่จะมีการคำนวณทางคณิตศาสตร์มากขึ้น ฯลฯ .... คำสั่ง hexdump ที่ต้องการจะเป็น
hexdump -v -x tf | sed s/'^[0-9]*\(.*\)/\1/' | sed s'/ *//g' | grep '[0-9]' | tr -d '\n' > tf.txt
หลังจากhexdump
ขั้นตอนกระบวนการเดียวกันsed
และcmp
สามารถใช้งานได้ รูปแบบที่ตรงกันจะต้องมีการอัปเดตเพื่อใช้อักขระ hexdump ascii ไม่ใช่การพิมพ์เลขฐานสิบหกแบบดิบ
วิธีการนี้ควรจัดการกับอักขระบรรทัดใหม่
LC_ALL=C
ดูเหมือนว่าจำเป็นสำหรับ OSX เป็นค่าเริ่มต้น โดยไม่ต้องมันสั่งให้ข้อผิดพลาดsed
RE error: illegal byte sequence
สิ่งนี้อาจไม่เป็นจริงในทุกแพลตฟอร์มและ / หรือระบบปฏิบัติการ OS
98
ผิด (ตัว96
พิมพ์ผิด) นี่เป็นเพราะคำตอบของคุณแสดงตัวอย่างรูปแบบสิ้นสุดที่มีสี่ไบต์ มิฉะนั้นงานที่ดี
96
อย่างไร (คำแนะนำ: คิดเกี่ยวกับมันผมเชื่อว่ามันผิด..) (2)0A
นี้จะไม่ทำงานถ้าหนึ่งในไบต์ที่รู้จักกันเป็นฐานสิบหก คุณสามารถขยายคำตอบให้ครอบคลุมกรณีนั้นได้หรือไม่? (3)LC_ALL=C
จำเป็นหรือไม่ คุณอธิบายได้ไหม (4) ในทำนองเดียวกันคุณสามารถอธิบายได้ว่าทำไมจึง-n 5000
จำเป็น (5) กรุณาวิจัย“ UUOC” ………………………………ทุก…………………ทุก…………………ทุก……………………ทุก……………………………………………………ทุก………… แก้ไขคำตอบของคุณเพื่อให้ชัดเจนและสมบูรณ์ยิ่งขึ้น