dd: несколько входных файлов

Если в вашей системе есть команда rev .

hex=030201
new_hex=$(printf %s "$hex" | dd conv=swab 2> /dev/null | rev)

Если у него есть команда tac или tail -r :

new_hex=$(echo "$hex" | fold -w 2 | tac | paste -sd '\0' -)

С zsh :

setopt extendedglob
new_hex=${(j::)${(s::Oa)${hex//(#b)(?)(?)/$match[2]$match[1]}}}

(как в dd : поменяйте местами пары символов, разделите на список отдельных символов ( s :: ), измените порядок ( Oa ) и объедините ( j :: )).

POSIXly:

new_hex=$(
  awk '
    BEGIN {
      hex = ARGV[1]; l = length(hex)
      for (i = 1; i < l; i += 2)
        new_hex = substr(hex, i, 2) new_hex
      print new_hex
    }' "$hex"
)

или

new_hex=$(echo "$hex" |
  sed -e 'G;:1' -e 's/\(..\)\(.*\n\)/\2\1/;t1' -e 's/.//')

С perl :

new_hex=$(perl -le 'print reverse(shift =~ /../g)' -- "$hex")
13
02.05.2016, 11:12
4 ответа

dd также может писать в стандартный вывод.

( dd if=file1 bs=1M count=99 skip=1
  dd if=file2 bs=1M count=10  ) > final_output
23
27.01.2020, 19:52

Имейте в виду, что dd - это необработанный интерфейс для read () , write ( ) и lseek () системный вызов. Вы можете надежно использовать его только для извлечения фрагментов данных из обычных файлов, блочных устройств и некоторых символьных устройств (например, / dev / urandom ), то есть файлов, для которых прочитано (buf, size) гарантированно вернет размер , пока не будет достигнут конец файла.

Для каналов, сокетов и большинства символьных устройств (например, ttys) у вас нет такой гарантии, если вы не выполните read () размера 1 или не используете расширение GNU dd . iflag = fullblock .

Или:

{
  gdd < file1 bs=1M iflag=fullblock count=99 skip=1
  gdd < file2 bs=1M iflag=fullblock count=10
} > final_output

Или:

M=1048576
{
  dd < file1 bs=1 count="$((99*M))" skip="$M"
  dd < file2 bs=1 count="$((10*M))"
} > final_output

Или с оболочками со встроенной поддержкой оператора поиска, например ksh93 :

M=1048576
{
  command /opt/ast/bin/head -c "$((99*M))" < file1 <#((M))
  command /opt/ast/bin/head -c "$((10*M))" < file2
}

Или zsh (при условии, что ваш head поддерживает здесь параметр -c ):

zmodload zsh/system &&
{
  sysseek 1048576 && head -c 99M &&
  head -c 10M < file2
} < file1 > final_output
8
27.01.2020, 19:52

С bashism, и функционально "бесполезным использованием cat", но наиболее близким к синтаксису, который использует ОП:

cat <(dd if=file1 bs=1M count=99 skip=1) \
    <(dd if=file2 bs=1M count=10) \
   > final_output

(При этом ответ Стивена Китта кажется наиболее эффективным возможным методом.)

3
27.01.2020, 19:52

Я не думаю, что вы можете легко читать несколько файлов в одном dd , но вы можете добавить, чтобы построить выходной файл в несколько шагов:

dd if=file1 bs=1M count=99 skip=1 of=final_output
dd if=file2 bs=1M count=10 of=final_output oflag=append conv=notrunc

Вам нужно указать как conv = notrunc , так и oflag = append . Первый позволяет избежать усечения вывода, второй начинает запись с конца существующего файла.

11
27.01.2020, 19:52

Теги

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