7

Здравствуйте, как я могу записать n байтов из одного файла в новый файл, начиная с позиции k используя Bash?

  • Например, если n = 60, k = 1 и размер файла = 100, тогда: 2-й файл будет состоять из 1-го байта до 60-го байта и будет иметь размер 60 байт
  • Например, если n = 40, k = 61 и размер файла = 100, тогда: 2-й файл будет состоять из 61-го байта до 100-го байта и будет иметь размер 40 байт

Возможно, мы работаем с двоичными файлами, а не с файлами ASCII, поэтому конкатенация из 2 половинок должна быть идентична исходному файлу!

(Это возможно с dd ?)

2 ответа2

11

Да. На странице man dd вы ищете что-то вроде:

dd bs=1 count=60 if=_filename_1_ of=_filename_2_
dd bs=1 skip=60 count=40 if=_filename_1_ of=_filename_2_

где _filename_n_ заменяется фактическим именем файла.

bs=1 означает, что count и skip являются счетчиками байтов. skip - это сколько пропустить; count , сколько копировать. Изменение количества байтов начинается с 0, а не с 1. Поэтому, чтобы начать с первого байта, используйте skip=0 (или оставьте skip неуказанным).

В качестве функции bash вы можете использовать:

# copy_nk(n, k, infile, outfile)
copy_nk() {
    dd bs=1 count="$1" skip="$2" ${3:+if="$3"} ${4:+of="$4"}
}

а затем назвать это как

copy_nk 60 0 infile.txt outfile.txt

(с k = 0 потому что байтовые номера начинаются с нуля).

С ${3:+...} вы можете оставить выходной файл или входной файл. Например,

cat infile.txt | copy_nk 60 0 > outfile.txt
5

Вот еще один подход, использующий группы команд head и bash:

{ head -c60 > /dev/null ; head -c40 > output.txt ; } < input.txt

Первая head здесь читает первые 60 байтов из input.txt и отправляет их в область битов.

Поскольку эти команды head находятся в группе команд, позиция файла в файле input.txt будет сохранена. Таким образом, вторая head будет читать следующие 40 байтов (от байта 61 до 100, используя индексирование на основе 1) и записывать его в output.txt.


Фактически этот метод может быть обобщен для предоставления функциональности, подобной split , но с дополнительным преимуществом возможности указать длину каждого выходного файла. Предположим, у нас есть 100-байтовый файл, который мы хотим разбить на куски размером 7, 50, 23 и остаток. Мы могли бы сделать:

{
    head -c7 > 7bytes.txt
    head -c50 > 50bytes.txt
    head -c23 > 23bytes.txt
    cat > remaining-bytes.txt
} < input.txt

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .