วิธีการส่งออกไฟล์จากออฟเซ็ตที่ระบุ แต่ไม่ใช่“ dd bs = 1 skip = N”?


28

วิธีการทำสิ่งที่ชอบdd if=somefile bs=1 skip=1337 count=31337000แต่มีประสิทธิภาพโดยไม่ใช้การอ่านและเขียนที่ไม่ใช่ 1 ไบต์

คาดว่าจะแก้ปัญหาได้:

  1. เป็นเรื่องง่าย (สำหรับผู้ที่ไม่ง่ายฉันสามารถเขียน Perl oneliner บางอย่างที่จะทำ)
  2. เพื่อรองรับออฟเซ็ตและความยาวขนาดใหญ่ (ดังนั้นแฮ็คที่มีขนาดบล็อกเป็น dd จะไม่ช่วย)

วิธีแก้ปัญหาบางส่วน (ไม่ง่ายพอการลองความยาวเท่ากันจะทำให้ซับซ้อนยิ่งขึ้น):

dd if=somefile bs=1000 skip=1 count=31337 | { dd bs=337 count=1 of=/dev/null; rest_of_pipeline; }
# 1337 div 1000 and 1337 mod 1000

คุณกำลังพยายามเปลี่ยนขนาดบล็อกที่ dd ใช้อยู่หรือไม่?
cmorse

เปลี่ยน blocksize => เปลี่ยนหน่วยสำหรับการข้ามและนับ
Vi

คำตอบ:


37

สิ่งนี้ควรทำ (บน gnu dd):

dd if=somefile bs=4096 skip=1337 count=31337000 iflag=skip_bytes,count_bytes

ในกรณีที่คุณกำลังใช้เช่นกันคุณอาจจะพิจารณาseek=oflag=seek_bytes

จากinfo dd:

`count_bytes'
      Interpret the `count=' operand as a byte count, rather than a
      block count, which allows specifying a length that is not a
      multiple of the I/O block size.  This flag can be used only
      with `iflag'.

`skip_bytes'
      Interpret the `skip=' operand as a byte count, rather than a
      block count, which allows specifying an offset that is not a
      multiple of the I/O block size.  This flag can be used only
      with `iflag'.

`seek_bytes'
      Interpret the `seek=' operand as a byte count, rather than a
      block count, which allows specifying an offset that is not a
      multiple of the I/O block size.  This flag can be used only
      with `oflag'.

ป.ล. : ฉันเข้าใจคำถามนี้เก่าและดูเหมือนว่ามีการใช้งานธงเหล่านี้หลังจากที่คำถามถูกถามมา แต่แรกเนื่องจากเป็นหนึ่งในผลการค้นหา google ครั้งแรกสำหรับการค้นหา dd ที่เกี่ยวข้องฉันทำฉันถึงแม้ว่าจะเป็นการปรับปรุงใหม่ ลักษณะ


2

ใช้กระบวนการเดียวเพื่อทิ้งไบต์เริ่มต้นทั้งหมดจากนั้นหนึ่งวินาทีเพื่ออ่านไบต์จริงเช่น:

echo Hello, World\! | ( dd of=/dev/null bs=7 count=1 ; dd bs=5 count=1 )

ที่สองddสามารถอ่านอินพุตกับสิ่งที่คุณพบว่ามีประสิทธิภาพขนาดบล็อก โปรดทราบว่านี่จะต้องมีกระบวนการพิเศษที่จะวางไข่ ขึ้นอยู่กับระบบปฏิบัติการของคุณที่จะต้องเสียค่าใช้จ่าย แต่มันอาจจะเล็กกว่าต้องอ่านไฟล์แบบหนึ่งต่อหนึ่งไบต์ (เว้นแต่คุณจะมีไฟล์ขนาดเล็กมากซึ่งในกรณีนี้จะไม่มีปัญหา)


มันจะทำงานได้ดีหรือไม่ (เช่นอย่าหน่วยความจำมากเกินไป) สำหรับออฟเซ็ตและการนับจำนวนมาก? dd if=/dev/sda bs=10000000001 | dd bs=255 count=1 | hd-> "dd: หมายเลขไม่ถูกต้อง` 10000000001 '"
Vi

@Vi หากคุณต้องการข้ามออฟเซ็ตขนาดใหญ่คุณควรทำการอ่านครั้งแรกเป็นซีรีย์บล็อก "นึกคิด" (ขึ้นอยู่กับแหล่งที่มาของคุณ) (16M) จากนั้นปล่อยซีรีส์บล็อกขนาดน้อยกว่า (512) ซึ่งจะอยู่ในหน่วยความจำ เพื่อ "ซูม" ข้อมูลของคุณก่อนที่คุณจะย่อส่วนแปลก ๆ ที่ไม่พอดีกับขนาดบล็อก (bs = 1 ด้านล่าง) จากนั้นอ่านบล็อกที่คุณต้องการ เช่นคุณต้องการอ่าน 255 ไบต์จากออฟเซ็ต 10000000001: dd if=/dev/sda bs=16M skip=596 count=1 | dd bs=512 skip=1522 count=1 | (dd bs=1 count=1 of=/dev/null ; dd bs=255 count=1)
RolKau

แน่นอนมันจะง่ายกว่าที่จะใช้read -nข้าม? จากนั้นhead -cให้นับ? เช่นcat somefile | (read -n 1337; head -c 31337000)หรือคุณสามารถทำได้โดยไม่ต้องมีกระบวนการพิเศษวางไข่:exec 3<somefile; read -n 1337 -u 3; head -c 31337000 <&3
Gannet

1

แทนที่จะbs=1ใช้bs=4096หรือมากกว่านั้น


2
จากนั้นมันจะอ่านจาก offset 1337 * 4096 แทน 1337
Vi

1
ใช่ฉันเข้าใจแล้วมันอาจจะง่ายกว่าที่จะเขียนสคริปต์ Python แบบง่าย ๆ เช่นในตัวอย่างนี้stackoverflow.com/questions/1035340/…ด้วยf.seek(1337)ก่อนใช้read(MY_CHUNK_SIZE)
ccpizza

รู้สึกว่าวิธีที่น่าเชื่อถือที่สุดคือการเขียนไฟล์ที่กำหนดเองได้ บางระบบไม่มี Python หรือ Ruby หรือแม้แต่ Perl : |
Trejkaz

1

คุณสามารถลองใช้คำสั่ง hexdump:

hexdump  -v <File Path> -c -n <No of bytes to read> -s <Start Offset>

หากคุณต้องการดูเนื้อหา:

#/usr/bin/hexdump -v -C mycorefile -n 100 -s 100
00000064 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 
00000074 00 00 00 00 01 00 00 00 05 00 00 00 00 10 03 00 |................| 
00000084 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 00 |......@.........| 
00000094 00 00 00 00 00 00 00 00 00 00 00 00 00 a0 03 00 |................| 
000000a4 00 00 00 00 00 10 00 00 00 00 00 00 01 00 00 00 |................| 
000000b4 06 00 00 00 00 10 03 00 00 00 00 00 00 90 63 00 |..............c.| 
000000c4 00 00 00 00 |....| 
000000c8 #

มันไม่เกี่ยวกับการดูไฟล์เป็นเลขฐานสิบหก มันเกี่ยวกับการแยกเนื้อหาของไฟล์ (เพื่อคัดลอกที่อื่น) จากออฟเซ็ตที่ระบุเป็นไบต์
วิ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.