我需要一个shell脚本程序,将大端序的十六进制数转换为小端序。
例如
- 输入:
my virtual address = 00d66d7e
- 输出:
7e6dd600
我如何在bash脚本中创建它?
我需要一个shell脚本程序,将大端序的十六进制数转换为小端序。
my virtual address = 00d66d7e
7e6dd600
我如何在bash脚本中创建它?
刚刚必须要这么做...但是从十进制到小端序...现在在这里适应:
echo 00d66d7e | tac -rs .. | echo "$(tr -d '\n')"
实现对于任意大小的无符号整数十六进制表示的所需结果。
(感谢MestreLion的建议 'tac -rs',非常好!)
tac
,至少GNU tac
,接受正则表达式作为分隔符,因此不需要使用grep:
echo "AABBCC" | tac -rs ..
- MestreLionecho -n 00d66d7e | tac -rs .. ; echo
,但这只是个人口味而已。 - Benoit Duffez对于32位地址,假设它是用零填充的:
v=00d66d7e
echo ${v:6:2}${v:4:2}${v:2:2}${v:0:2}
# 7e6dd600
根据Karoly的回答,您可以使用以下脚本来读取参数或管道输入并进行大小端转换:
#!/bin/bash
# check 1st arg or stdin
if [ $# -ne 1 ]; then
if [ -t 0 ]; then
exit
else
v=`cat /dev/stdin`
fi
else
v=$1
fi
i=${#v}
while [ $i -gt 0 ]
do
i=$[$i-2]
echo -n ${v:$i:2}
done
echo
比如,您可以将此脚本保存为endian.sh,并使用以下命令使其可执行:
chmod u+x endian.sh
那么:
echo 00d66d7e | ./endian.sh
为您提供:
7e6dd600
对于不同长度的字符串:
echo d76f411475428afc90947ee320 | ./endian.sh
结果将是:
20e37e9490fc8a427514416fd7
#更新: 修改了脚本,使其可以通过参数或从stdin输入,以满足Freewind的要求。现在:
./endian.sh d76f411475428afc90947ee320
也可以工作,并提供给您:
20e37e9490fc8a427514416fd7
./endian.sh d76f411475428afc90947ee320
一起工作?谢谢! - Freewindv=0x12345678
v2=$(( (v<<8 & 0xff00ff00) | (v>>8 & 0xff00ff) ))
v2=$(( (v2<<16 & 0xffff0000) | v2>>16 ))
printf '0x%08x\n' $v2
${v:6:2} is for bash.
0x
或\x
前缀和多种输出格式,并可使用如下:
$ be2le d76f411475428afc90947ee320 0xaaff 0xffa '\x3'
20e37e9490fc8a427514416fd7
0xffaa
0xfa0f
\x03
be2le bash脚本
#!/bin/bash
args=()
format=preserve
delimiter="\n"
nonewline=false
join=false
strip=false
while (( "$#" )); do
case "$1" in
-h|--help) usage;;
-f) format=$2; shift 2;;
--format=*) format="${1#*=}"; shift;;
-d) delimiter=$2; 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 $1 specified"; exit 1;;
*) args=( "${args[@]}" "$1" ); 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
这个脚本是用于翻转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