Як вивести файл із зазначеного зміщення, але не “dd bs = 1 пропустити = 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

Ви намагаєтесь змінити розмір блоку, який використовує ДД?
cmorse

Змінено блочний розмір => змінені одиниці для пропуску та рахунку
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. Якщо ви хочете пропустити величезний зсув, тоді вам слід зробити початкове читання як серію блоків розміру "в ідеалі" (залежно від вашого джерела) (16 М), а потім скинути ряд блоків меншого розміру (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
Тоді він буде читати із зміщення 1337 * 4096 замість 1337
Vi.

1
Ага, я бачу, тоді, мабуть, буде простіше написати простий скрипт Python, наприклад, як у цьому прикладі stackoverflow.com/questions/1035340/… з f.seek(1337)перед використаннямread(MY_CHUNK_SIZE)
ccpizza

Схоже, найнадійніший спосіб - це, мабуть, написати користувальницький виконуваний файл. У деяких системах немає Python, Ruby або навіть Perl. : |
Трежказ

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 #

Справа не в тому, щоб переглядати файл як шістнадцятковий. Йдеться про вилучення вмісту файлу (копіювати його кудись, наприклад) із зазначеного зміщення в байтах.
Ві.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.