Đảo ngược một số thập lục phân trong bash


10

Có một lệnh đơn giản để đảo ngược một số thập lục phân?

Ví dụ: đã cho số thập lục phân:

030201

Đầu ra phải là:

010203

Sử dụng revlệnh, tôi nhận được như sau:

102030

Cập nhật

$ 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
Xin đừng thêm câu trả lời cho câu hỏi của bạn.
mèo

@cat Tôi đã thêm câu trả lời vì câu trả lời phù hợp với tôi, là ở phần bình luận của câu trả lời được chọn. Nhưng tôi chấp nhận loại bỏ nó.
Iñaki Murillo

2
Bạn có thể thêm nó dưới dạng câu trả lời bằng cách nhấp vào nút "Trả lời câu hỏi này" bên dưới hộp câu trả lời (tự trả lời được khuyến khích) và bạn không nên đặt câu hỏi vào câu hỏi.
con mèo

2
Lập trình viên C trong tôi muốn nói "010203" là số bát phân, không phải số hex (0x10203)
nhập vào

@infixed Bạn không sai, nhưng tôi muốn một câu trả lời coi 010203là thập lục phân, mặc dù tôi không sử dụng 0x
Iñaki Murillo

Câu trả lời:


10

Bạn có thể chuyển đổi nó thành nhị phân , đảo ngược các byte , tùy ý xóa các dòng mới theo dõi rev<2.24 và chuyển đổi lại:

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

Sử dụng

$ 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

Điều này không hoạt động nếu chuỗi chứa byte NUL, vì revsẽ cắt bớt đầu ra tại điểm đó.


2
Tôi nhận được 0102030athay vì010203
Iñaki Murillo

@ l0b0 và tôi cũng vậy, nhận được0102030a
Hồi giáo

2
@ IñakiMurillo trong revphiên bản của bạn 2.20.1; sử dụng công thức nàyxxd -revert -plain <<< '030201' | LC_ALL=C rev | tr -d '\n'| xxd -plain
بارپابابا

2
revtrước khi phiên bản 2.24có lỗi dòng mới. chi tiết github.com/karelzak/util-linux/commit/...
بارپابابا

1
Nó không hoạt động nếu chuỗi hex chứa byte NUL '00'.
Sylvain Leroux

10

Nếu hệ thống của bạn có một revlệnh.

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

Nếu nó có một tachoặc tail -rlệnh:

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

Với zsh:

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

(giống như trong ddcách tiếp cận: hoán đổi các cặp ký tự, chia thành danh sách các ký tự riêng lẻ ( s::), đảo ngược thứ tự ( Oa) và nối ( 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"
)

Hoặc là

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

Với perl:

new_hex=$(perl -le 'print reverse(shift =~ /../g)' -- "$hex")

3
Tôi sẽ đề nghị perl -F'(..)' -lane 'print reverse(@F)':)
Sundeep

1
@Seepeep, tốt đẹp. Tôi không biết người ta có thể sử dụng -Fnhư thế. (Tôi có thể thấy nó được mô tả trong split()hướng dẫn bây giờ).
Stéphane Chazelas

1
theo như tôi biết, -Fvề cơ bản là tách ra $_.. ngoài việc sử dụng regex như -F'/"\K\|(?=")/'người ta có thể chỉ định số lần phân tách cũng như -F'/:/,$_,2'... sử dụng ()nếu phân tách cũng phải được ghi lại
Sundeep

Thay vì sử dụng dán, bạn có thể sử dụngtr -d '\n'
AKHolland

10

Với fold+ tac+ tr:

$ echo 030201|fold -w2|tac|tr -d "\n"
010203
  • fold - chia mỗi 2 byte
  • tac - mèo ngược
  • tr - xóa dòng mới

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

Điều này hoàn nguyên từng dòng thập lục phân:

  • /(..)/g đưa ra một danh sách với các trận đấu được chụp

4

(vì lợi ích của sự hoàn chỉnh)

$ echo 030201 | grep -o .. | tac | paste -sd '' -
010203

1
Điều này hoạt động nếu byte NUL '00' ở đầu vào.
Sylvain Leroux

0

Dựa trên câu trả lời của Ipor Sirceller https://unix.stackexchange.com/a/321867/337458 Tôi muốn giới thiệu điều này trong bạn ~/.bashrcđể có một lệnh hay mà bạn chỉ cần gọi:

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

$> hex_inverse 030201

010203
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.