bash 需要一个 shell 脚本来将大端转换为小端

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22296839/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 09:52:10  来源:igfitidea点击:

need a shell script to convert big endian to little endian

bashshellendianness

提问by Rajiv

I need a shell script program to print the hexadecimal number from big endian to little endian

我需要一个shell脚本程序来打印从大端到小端的十六进制数

For example

例如

  • Input: my virtual address = 00d66d7e
  • Output: 7e6dd600
  • 输入: my virtual address = 00d66d7e
  • 输出: 7e6dd600

How can I can I create this in a bash script?

我怎样才能在 bash 脚本中创建它?

回答by Karoly Horvath

For 32 bit addresses, assuming it's zero padded:

对于 32 位地址,假设它是零填充的:

v=00d66d7e 
echo ${v:6:2}${v:4:2}${v:2:2}${v:0:2}
# 7e6dd600

回答by hutheano

Based on Karoly's answeryou could use following script, reading piped input:

根据Karoly 的回答,您可以使用以下脚本,读取管道输入:

#!/bin/bash

# check stdin
if [ -t 0 ]; then exit; fi

v=`cat /dev/stdin`
i=${#v}

while [ $i -gt 0 ]
do
    i=$[$i-2]
    echo -n ${v:$i:2}
done

echo

For e.g. you could save this script as endian.sh and make it executable with:

例如,您可以将此脚本保存为 endian.sh 并使其可执行:

chmod u+x endian.sh

Then:

然后:

echo 00d66d7e | ./endian.sh

gives you:

给你:

7e6dd600

For a different length string:

对于不同长度的字符串:

echo d76f411475428afc90947ee320 | ./endian.sh

result would be:

结果将是:

20e37e9490fc8a427514416fd7

回答by Brian Chrisman

Just had to do this... but from decimal to little endian.. adapting that here:

只需要这样做......但从十进制到小端..在此处进行调整:

echo 00d66d7e | tac -rs .. | echo "$(tr -d '\n')"

achieves the desired result, for arbitrarily sized hexadecimal representations of unsigned integers.

对于无符号整数的任意大小的十六进制表示,实现了预期的结果。

(h/t 'tac -rs' MestreLion, very nice!)

(h/t 'tac -rs' MestreLion,非常好!)

回答by Vouze

This works for dash (and many other shells) :

这适用于破折号(和许多其他外壳):

v=0x12345678
v2=$(( (v<<8 & 0xff00ff00) | (v>>8 & 0xff00ff) ))
v2=$(( (v2<<16 & 0xffff0000) | v2>>16 ))
printf '0x%08x\n' $v2

Result should be "0x78563412"

结果应该是“0x78563412”

${v:6:2} is for bash.

回答by antonpinchuk

This script is for flipping 16 bit data.

此脚本用于翻转 16 位数据。

#!/bin/bash

if [ -t 0 ]; then exit; fi

data=`cat /dev/stdin | od -An -vtx1 | tr -d ' ' | tr -d '\n'`
length=${#data}

i=0
while [ $i -lt $length ]; do
    echo -n -e "\x${data:$[$i+2]:2}"
    echo -n -e "\x${data:$[$i]:2}"
    i=$[$i+4]
done

回答by NoodleOfDeath

In response to Freewind's comment request and building off of hutheano's great answer, I wrote my own bash script and I include a condensed version below. The full script can be downloaded here.

为了响应 Freewind 的评论请求并基于hutheano 的出色回答,我编写了自己的 bash 脚本,并在下面包含了一个精简版本。完整的脚本可以在这里下载。

The following implementation accounts for odd length strings, 0xor \xprefixes, and multiple output formatsand can be used like the following:

以下实现考虑了奇数长度的字符串0x\x前缀以及多种输出格式,可以像下面这样使用:

$ be2le d76f411475428afc90947ee320 0xaaff 0xffa '\x3'
20e37e9490fc8a427514416fd7
0xffaa
0xfa0f
\x03

be2lebash script

be2lebash 脚本

#!/bin/bash

args=()

format=preserve
delimiter="\n"
nonewline=false
join=false
strip=false

while (( "$#" )); do
    case "" in
        -h|--help) usage;;
        -f) format=; shift 2;;
        --format=*) format="${1#*=}"; shift;;
        -d) delimiter=; shift 2;;
        --delimiter=*) delimiter="${1#*=}"; shift;;
        -n|--no-newline) nonewline=true; shift;;
        -j|--join) join=true; shift;;
        -s|--strip-null) strip=true; shift;;
        -*|--*) echo "Error: unsupported flag  specified"; exit 1;;
        *) args=( "${args[@]}" "" ); shift;;
    esac
done

case "$format" in
    preserve);;
    int) prefix="0x";;
    char) prefix="\x";; 
    raw) ;;
    *) echo "Error: unsupported format $format"; exit 1;;
esac

n=0
parts=()
for arg in ${args[@]}; do

    digest=""
    prefix=""

    # remove prefix if string begins with "0x"
    if [[ $arg =~ ^[0\]x ]]; then
        if [ "$format" == "preserve" ]; then
            prefix=${arg:0:2}
        fi
        arg=${arg:2}
    fi

    # zero-pad if string has odd length
    if [ $[${#arg} % 2] != 0 ]; then
        arg="0$arg"
    fi

    part=""
    i=${#arg}
    while [ $i -gt 0 ]; do
        i=$[$i-2]
        byte=${arg:$i:2}
        if [ $strip == true ] && [ -z "$part" ] && [ $byte == "00" ]; then
            continue
        fi
        case "$format" in
            int) part="$part"'0x'"$byte ";;
            char) part="$part\x$byte";;
            raw) part="$part$(printf "%b" "\x$byte")";;
            *) part="$part$byte";;
        esac
    done

    digest="$prefix$digest$part"

    parts=( "${parts[@]}" "$digest" )
    n=$[$n+1]

done

if [ $join == true ]; then
    case "$format" in
        *) printf "%s" "${parts[@]}";;
    esac
else
    i=0
    for part in "${parts[@]}"; do
        if [[ $(($i + 1)) < $n ]]; then
            printf "%s$delimiter" "$part"
        else
            printf "%s" "$part"
        fi
        i=$(($i+1))
    done
fi

if [ $nonewline == false ]; then
    echo
fi