Как подставить/заменить байты в бинарном файле с помощью оболочки

можно ли заменить байты из бинарного файла myfile из одной конкретной позиции в другую с помощью dd в цикле или удобнее использовать другую команду?

Идея состоит в том, чтобы заменить блок B в позиции position2 блоком A в position1 в цикле.

ПСЕВДОКОД

  @ l = 0

  while (l <= bytelength of myfile)
      copy myfile (from position1 to A+position1)  myfile from (position2 to B+position2)
      @ position1 = position1+steplength
      @ position2 = position2+steplength
      @ l = l+steplength

  end

person MichaelScott    schedule 12.03.2013    source источник
comment
Хотя это возможно, я бы не стал использовать командный язык оболочки для такого типа манипуляций с файлами. Используйте язык с лучшей поддержкой для этого типа файлового ввода-вывода. В любом случае, вы перезаписываете байты в position2 или просто меняете порядок байтов в файле?   -  person chepner    schedule 12.03.2013
comment
Я хочу перезаписать их, если это возможно...   -  person MichaelScott    schedule 12.03.2013
comment
возможный дубликат Как перезаписать некоторые байты двоичный файл с dd?   -  person user2284570    schedule 08.01.2014


Ответы (1)


Следующие строки кода в текстовом файле будут делать примерно то, о чем (я думаю) вы просите: скопировать файл из одного места в другое, но заменить блок байтов в одном месте блоком из другого места; он использует dd по запросу. Однако он создает отдельный выходной файл — это необходимо для обеспечения отсутствия конфликтов независимо от того, находится ли «входной» блок до или после «замещающего» блока. Обратите внимание, что он ничего не сделает, если расстояние между A и B меньше размера заменяемого блока - это приведет к перекрытию, и неясно, хотите ли вы, чтобы байты в перекрывающейся области были «концом блока». А" или "начало копии А".

Сохраните это в файле с именем blockcpy.sh и измените разрешения, чтобы включить execute (например, chmod 755 blockcpy.sh). Запустите его с

./blockcpy.sh inputFile outputFile from to length

Обратите внимание, что смещения «от» и «до» имеют нулевую базу: поэтому, если вы хотите скопировать байты, начиная с начала файла, аргумент from равен 0.

Вот содержимое файла:

#!/bin/bash
# blockcpy file1 file2 from to length
# copy contents of file1 to file2
# replacing a block of bytes at "to" with block at "from"
# length of replaced block is "length"
blockdif=$(($3 - $4))
absdif=${blockdif#-}
#echo 'block dif: ' $blockdif '; abs dif: ' $absdif
if [ $absdif -ge $5 ]
  then
    # copy bytes up to "to":
    dd if=$1 of=$2 bs=$4 count=1 status=noxfer 2>0
    # copy "length" bytes from "from":
    dd bs=1 if=$1 skip=$3 count=$5 status=noxfer 2>0 >> $2
    # copy the rest of the file:
    rest=$((`cat $1 | wc -c` - $4 - $5))
    skip=$(($4 + $5))
    dd bs=1 if=$1 skip=$skip count=$rest status=noxfer 2>0 >> $2
    echo 'file "'$2'" created successfully!'
  else
    echo 'blocks A and B overlap!'
fi

2>0 «Магия nix» подавляет вывод из stderr, который в противном случае отображается в выводе (типа: «16+0 records in»).

person Floris    schedule 03.04.2013