Если в вашей системе есть команда 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")
dd
также может писать в стандартный вывод.
( dd if=file1 bs=1M count=99 skip=1
dd if=file2 bs=1M count=10 ) > final_output
Имейте в виду, что 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
С bashism, и функционально "бесполезным использованием cat", но наиболее близким к синтаксису, который использует ОП:
cat <(dd if=file1 bs=1M count=99 skip=1) \
<(dd if=file2 bs=1M count=10) \
> final_output
(При этом ответ Стивена Китта кажется наиболее эффективным возможным методом.)
Я не думаю, что вы можете легко читать несколько файлов в одном 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
. Первый позволяет избежать усечения вывода, второй начинает запись с конца существующего файла.