Достижение подобного hexdump формата, который включает двоичные строки на командной строке?

Сделайте это вместо этого:

find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' -delete

Вы могли также использовать регулярные выражения:

find . -type f -iregex '.*\.\(xml\|png\|jpeg\|gif\)$' -delete
7
13.06.2014, 00:26
3 ответа

В случае сбоя программы дампа с подходящими параметрами дампа вы всегда можете что-то сколотить, используя как hexdump , так и xdd , а затем объединить вывод с помощью вставки. Это некрасиво, но с использованием оболочки, поддерживающей подстановку процессов (подойдет bash ):

mkfifo fifo
echo -e '\x00\x01\x02\x03' |
  tee fifo |
  paste -d' ' \
    <(hexdump -v -e '1/1 "%_ad: "' -e '4/1 "%02X "' -e '1/1 " :\n"') \
    <(xxd -b -c 4 fifo | cut -d' ' -f 2-)

Вывод:

0: 00 01 02 03 : 00000000 00000001 00000010 00000011  ....
4: 0A          : 00001010                             .
5
27.01.2020, 20:17

Вот мое предложение использовать Perl, используя его спецификаторы форматирования для функции pack()/unpack(); тестовый вызов будет подобен:

$ echo -e '\x00\x01\x02\x03' | perl hexdump-00.pl --offset 120 --group 4 --add '(H2)*' --add '(B8)*' 
Opening '' STDIN
Cannot seek!
0
00000000: 00 01 02 03 00000000 00000001 00000010 00000011  '....'
00000004: 0a 00001010  '.'

Вставлять строковые маркеры между ними довольно сложно - но хорошо то, что внутри можно "сгруппировать" байты - например, можно сгруппировать два байта и интерпретировать их как знаковое (короткое) целое число, например:

$ perl -e 'print pack("s*\n", (-124))' | hexdump -C
00000000  84 ff                                             |..|
00000002

$ echo -e '\x00\x01\x84\xff' | perl hexdump.pl \
  --offset 120 --group 4 \
  --add '(H2)*' \
  --add '(B8)*' \
  --add '(s2)*'
Opening '' STDIN
Cannot seek!
0
00000000: 00 01 84 ff 00000000 00000001 10000100 11111111 256 -124  '....'
00000004: 0a 00001010  '.'

Вот hexdump-00.pl:

#!/usr/bin/perl

# perl hexdump-00.pl --offset 120 --group 4 --add '(H2)*' --add '(B8)*' test.file

use strict;
use warnings;
use Getopt::Long;
use Fcntl qw(SEEK_CUR SEEK_SET);
my $offset = 0;
my $groupsize = 1;
my $length = 128;
my @list=();
my $result = GetOptions (
  "offset=i" => \$offset,
  "group=i"   => \$groupsize,
  "length=i"   => \$length,
  "add=s" => \@list,
);
my $inputfname="";
my $inputfh;
$inputfname = $ARGV[0] if defined $ARGV[0];
if (($inputfname eq "") || ($inputfname eq "-")) {
  printf(STDERR "Opening '%s' STDIN\n", $inputfname);
  $inputfh = *STDIN;
} else {
  printf(STDERR "Opening '%s'\n", $inputfname);
  open ($inputfh, "<$inputfname");
}

binmode($inputfh);
my $startaddr=0;
if( not(defined($startaddr = sysseek($inputfh, $offset-1, SEEK_SET))) ) {
  printf(STDERR "Cannot seek!\n");
  #~ $startaddr = sysseek($inputfh, 0, 0); // cannot reset like this
  $startaddr = 0; # just avoid errors
}
print(STDERR $startaddr . "\n");

my $buffer=undef;
my $nread;
my $total=0;
while (($nread=sysread($inputfh, $buffer, $groupsize)) > 0) { # , $startaddr
  #~ printf("%08X: nr: %d, buf '%s'\n",$startaddr,$nread,$buffer);
  printf("%08X: ", $startaddr);
  foreach my $tformat (@list) {
    foreach my $tentry (unpack($tformat, $buffer)) {
      printf("%s ", $tentry);
    }
  }
  (my $newbuf = $buffer) =~ s/[^[:print:]]/./g; # make non-printable into '.'
  printf(" '%s'", $newbuf);
  print("\n");
  $startaddr += $nread;
  $total += $nread;
  if ($total > $length) { last; }
}

close($inputfh);
3
27.01.2020, 20:17

Вот немного sed to coax dc to translate od's output to base 2:

od -t d1z -w4 -v -N12 </dev/urandom |
sed -e '1i2o' -e 's/.*/[&]p/p;$d
    s/>/]n [>/;s/[^ ]*/&]n [/;h;s/>.*//;
    s/ -/ _/g;s/ [^] [][^ ]*/ ]n&n [ /g;G
    s/\n[^>]*//' | 
dc

It's a little easier now - не говоря уже о том, что быстрее - но это все равно не королева красоты. Она также выводит десятичное и базовое 2 значения всех байтов.

Когда я запускаю его, я получаю:

0000000  -43  125 -117  -39  >.}..<
0000000  -101011   1111101  -1110101   -100111   >.}..<
0000004   62   28   80   61  >>.P=<
0000004   111110    11100    1010000    111101   >>.P=<
0000010    6   14  120  -16  >..x.<
0000010    110    1110   1111000   -10000   >..x.<
0000014

Или...

echo aBcD | od -t d1z -w4 -v | sed ... | dc


0000000   97   66   99   68  >aBcD<
0000000   1100001    1000010    1100011    1000100   >aBcD<
0000004   10                 >.<
0000004   1010                  >.<
0000005

Ширина поля может потребовать немного работы, но она вся ваша. Вам не нужна опция -N12 - я просто использовал ее, чтобы не подавиться бесконечной трубой псевдослучайных данных. А опция -w4 задает 4 байта на строку, но вы должны быть в состоянии использовать любое количество байт. Также команда 1i2o sed является командой dc относительно ее выходной базы - 2 для двоичной - но любая база между 2 и 16 должна работать так же хорошо. Если вы хотите посмотреть, например, шестнадцатеричный и вывод базы 2, вам нужно добавить '16i' к первому оператору sed и изменить опцию od -t d1z на t x1z.

Другие опции включают в себя...

printf делает это:

printf '%o\n%x\n' 128 128

200

80

... даже....

printf '%o\n%x\n' "'a" "'a"

141

61

Двоичный файл не так прост, но bc может сделать все это, если вы установите его obase= в соответствии со своими спецификациями:

printf 'obase=2;%d
        obase=8;%d
        obase=16;%d
        obase=2;%d
        ' 64 128 "'A" "'a" |
bc

OUTPUT

1000000
200
41
1100001

dc не так просто:

printf '%do%dn10P' 2 64 8 128 16 "'A" 2 "'a" |dc

OUTPUT

1000000
200
41
1100001

Do man dc bc для более подробной информации.

И опять же, для файловых потоков вы всегда можете использовать od:

for o in o d x ; do
    echo aBcD | 
    od -A n -t ${o}1z -v -w4
done

OUTPUT

 141 102 143 104  >aBcD<
 012              >.<
  97  66  99  68  >aBcD<
  10              >.<
  61  42  63  44  >aBcD<
  0a              >.<

С помощью ^that^ я говорю od не печатать смещения - что, как я сейчас догадываюсь, - что мне нужны выходы -type o, d, или x по одному байту за раз и что я хочу, чтобы ASCII представлениеz каждого байта было приложено к концу строки, -v erbosely (так что это не просто выводит мне 0* для 0000) на -w4 байт на строку.

Без -A n печатает:

0000000 141 102 143 104  >aBcD<
0000004 012              >.<
0000005
0000000  97  66  99  68  >aBcD<
0000004  10              >.<
0000005
0000000  61  42  63  44  >aBcD<
0000004  0a              >.<
0000005

И любая комбинация dc bc od, конечно же, возможна на |pipeline.

2
27.01.2020, 20:17

Теги

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