Записать n байтов из файла в другой в Bash

2376
PiNewbie

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

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

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

(Возможно ли это с dd?)

7
Смотрите `dd` и его опции` skip`, `count` и` ibs`. choroba 7 лет назад 2

2 ответа на вопрос

10
cxw

Да. На странице 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" $ $ } 

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

copy_nk 60 0 infile.txt outfile.txt 

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

С помощью $вы можете оставить выходной файл или входной файл. Например,

cat infile.txt | copy_nk 60 0 > outfile.txt 
Счетчик индекса начинается с 0 или 1. Так что я думаю, что если пропуск равен 1, это означает, что он начинается со 2-го байта. Это верно? PiNewbie 7 лет назад 0
5
Digital Trauma

Вот еще один подход с использованием 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 
Вы можете испортить файловую систему с помощью `head` так же легко (или просто), если вы достаточно сумасшедший, чтобы передать ее вывод на блочное устройство. Конечно, вы бы этого не делали - вместо этого вы использовали бы `dd` или что-то еще, предназначенное для этой работы. Причина пугающей репутации `dd` заключается в том, что она достаточно надежна, чтобы вы * могли * более или менее безопасно использовать ее для опасных по своей природе задач, таких как клонирование образов дисков, если вы достаточно осторожны. Конечно, некоторые люди этого не делают и будут портить свой диск - но причина этого не в том, что они использовали `dd`, а в том, что они в первую очередь возились с` / dev / sda`. Ilmari Karonen 7 лет назад 3
Очень хорошо! Я не знал о `head -c`. cxw 7 лет назад 0
Вы можете повредить файловую систему, только если вы работаете от имени пользователя root. И если вы root, вы можете испортить его практически любой утилитой, которая пишет в файлы. Barmar 7 лет назад 1
@IlmariKaronen Достаточно справедливо - я удалил ненужную антидопинговую FUD. Digital Trauma 7 лет назад 0

Похожие вопросы