Зворотне шістнадцяткове число в басі


10

Чи є проста команда повернути шістнадцяткове число?

Наприклад, враховуючи шістнадцяткове число:

030201

Вихід повинен бути:

010203

За допомогою revкоманди я отримую наступне:

102030

Оновлення

$ bash --version | head -n1
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
$ xxd -version
xxd V1.10 27oct98 by Juergen Weigert
$ rev --version
rev from util-linux 2.20.1

2
Будь ласка, не додайте відповіді на своє запитання.
кіт

@cat Я додав відповідь, тому що той, хто працював на мене, знаходиться в коментарях до вибраної відповіді. Але я нормально її знімаю.
Іньякі Мурільо

2
Ви можете додати його як відповідь, натиснувши кнопку "Відповісти на це питання" під полем відповідей (самовідповіді рекомендується), і вам слід просто не ставити це питання.
кіт

2
C програміст в мені хоче сказати , «010203» це вісімкове число, а НЕ шестнадцатиричное число (0x10203)
інфіксальний

@infixed Ви не помиляєтесь, але я хотів відповісти, що трактує 010203як шістнадцятковий, хоча я не використовую 0x
Iñaki Murillo

Відповіді:


11

Ви можете перетворити його у двійковий , змінити байти , необов'язково видалити проміжні рядки rev<2,24 та повернути їх назад:

$ xxd -revert -plain <<< 030201 | LC_ALL=C rev | tr -d '\n' | xxd -plain
010203

Використання

$ bash --version | head -n1
GNU bash, version 4.3.42(1)-release (x86_64-redhat-linux-gnu)
$ xxd -version
xxd V1.10 27oct98 by Juergen Weigert
$ rev --version
rev from util-linux 2.28.2

Це не працює, якщо рядок містить байт NUL, оскільки revбуде обрізаний вихід у цій точці.


2
Я отримую 0102030aзамість010203
Іньякі Мурільо

@ l0b0 і теж мене, діставайся0102030a
Баба

2
@ IñakiMurillo у вашій revверсії 2.20.1; використовуйте цей форматxxd -revert -plain <<< '030201' | LC_ALL=C rev | tr -d '\n'| xxd -plain
Баба

2
revперед версією 2.24є нова помилка рядка. детальніше github.com/karelzak/util-linux/commit/…
Баба

1
Він не працює, якщо шістнадцятковий рядок містить байт NUL '00'.
Сільвен Леру

10

Якщо у вашій системі є 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")

3
Я збирався запропонувати perl -F'(..)' -lane 'print reverse(@F)':)
Sundeep

1
@Sundeep, приємно. Я не знав, що можна так використовувати -F. (Я бачу, як це описано в split()посібнику зараз).
Стефан Хазелас

1
наскільки я знаю, -Fв основному це розбиття на $_.. окрім використання регулярного виразу, як -F'/"\K\|(?=")/'можна вказати також кількість розщеплень ... як -F'/:/,$_,2'... використання, ()якщо роздільник повинен бути захоплений
Sundeep

Замість пасти ви могли використовуватиtr -d '\n'
AKHolland

10

З fold+ tac+ tr:

$ echo 030201|fold -w2|tac|tr -d "\n"
010203
  • fold - розділити кожні 2 байти
  • tac - зворотний кіт
  • tr - видалити нові рядки

4
perl -nE 'say reverse /(..)/g'

Це повертає кожну шістнадцяткову лінію:

  • /(..)/g будує список із захопленими сірниками


0

Виходячи з відповіді Іпора Сірцера https://unix.stackexchange.com/a/321867/337458, я рекомендую це у вашій ~/.bashrcкоманді, щоб мати гарну команду, яку ви можете просто зателефонувати:

function hex_inverse() {
    echo ${1} | fold -w2 | tac | tr -d "\n" ; echo "" 
}

$> hex_inverse 030201

010203
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.