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
need a shell script to convert big endian to little endian
提问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, 0x
or \x
prefixes, 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