bash 生成特定范围的十六进制数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5517500/
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
Generating hex numbers of a certain range
提问by Dave
I need a simple way to generate a .txt file with a list of semi-colon delimited hex numbers between (inclusive) a certain start and finish value.
我需要一种简单的方法来生成一个 .txt 文件,其中包含(包含)某个起始值和结束值之间的以分号分隔的十六进制数列表。
For example:
例如:
If I enter 0and FFFit would pad the output with zeroes to the largest number:
如果我输入0,FFF它将用零填充输出到最大数字:
000;001;002;003;004;005;006;007;008;009;00A;00B;00C;00D;00E;00F;010;011;....FFF;
000;001;002;003;004;005;006;007;008;009;00A;00B;00C;00D;00E;00F;010;011;...FFF;
If I enter FFFand 1200it would output those values...etc:
如果我输入FFF和1200它会输出这些值...等等:
0FFF;1000;1001;1002;.....1200;
0FFF;1000;1001;1002;.....1200;
Any suggestions? I'm not a programmer so the best, simplest way to do this is way beyond me.
有什么建议?我不是程序员,所以最好、最简单的方法超出了我的范围。
回答by Jens
Here's a script that's portable (any POSIX shell will do), should work blazingly fast (no forks to nawk, bc, etc...) and adheres to the poster's spec.
这是一个可移植的脚本(任何 POSIX shell 都可以),应该工作得非常快(没有对 nawk、bc 等的分叉)并且符合海报的规范。
#!/bin/sh
#
# hexcount - POSIX Shell script to count from to in hex,
# separated by ";" and with the precision set to the
# maximum digits of and .
# Usage: hexcount lo hi
# Example: hexcount FFF 1200
from= to=
if test "${#from}" -gt "${#to}"; then
format="%0${#from}X;"
else
format="%0${#to}X;"
fi
from=$(printf '%d' "0x$from") to=$(printf '%d' "0x$to")
while test "$from" -le "$to"; do
printf "$format" "$from"
from=$((from+1))
done
printf '\n'
Ain't printf cool?
printf 是不是很酷?
回答by mcau
Another Attempt (still needs seq but not bc) - works in cygwin and linux:
另一种尝试(仍然需要 seq 但不需要 bc) - 适用于 cygwin 和 linux:
seq 0 255 | while read n; do printf "%04X;" $n; done
The inputs are decimal, but the output is capitalised hex and you can change the digits to show by updating the "04" part of the printf format string
输入是十进制,但输出是大写的十六进制,您可以通过更新 printf 格式字符串的“04”部分来更改要显示的数字
回答by William Cates
I just like to use simple for loops. You can add as many nested loops as you like for each digit:
我只是喜欢使用简单的 for 循环。您可以为每个数字添加任意数量的嵌套循环:
for i in {0..9} {a..f}; do for x in {0..9} {a..f}; do for y in {0..9} {a..f}; do printf "$i$x$y;"; done; done; done
Output should look like this:
输出应如下所示:
000;001;002;003;004;005;006;007;008;009;00a;00b;00c;00d;00e;00f;010;011;012;013;014;015;016;017;018...ff8;ff9;ffa;ffb;ffc;ffd;ffe;fff;
That was a one-liner, but let me give it some structure:
那是一个单行,但让我给它一些结构:
for i in {0..9} {a..f}
do
for x in {0..9} {a..f}
do
for y in {0..9} {a..f}
do
printf "$i$x$y;"
done
done
done
回答by chuckx
Here's an implementation tested in KSH on OpenBSD (should work with any Bourne shell, doesn't rely on bashfeatures).
这是在 OpenBSD 上的 KSH 中测试的一个实现(应该适用于任何 Bourne shell,不依赖于bash功能)。
#!/bin/sh
START=
END=
function h2d {
echo "ibase=16; $@"|bc
}
function d2h {
echo "obase=16; $@"|bc
}
# convert to decimal
START_DEC=`h2d ${START}`
END_DEC=`h2d ${END}`
# find length of last hex number
LENGTH=`expr ${#END} - 1`
for i in `nawk "BEGIN{ for(i=${START_DEC};i<=${END_DEC};i++) print i}"`
do
# convert output to hex
OUTPUT=`d2h ${i}`
# calculate output length
OUTPUT_LENGTH=`expr ${#OUTPUT}`
# calculate required padding
PAD_LENGTH=`expr ${LENGTH} - ${OUTPUT_LENGTH}`
# output padding
for j in `nawk "BEGIN{ for(j=0;j<=${PAD_LENGTH};j++) print j}"`
do
echo -n 0
done
# output number
echo -n ${OUTPUT}\;
done
# for the newline
echo
Sample output:
示例输出:
$ ./hex-range.sh 91 FF
91;92;93;94;95;96;97;98;99;9A;9B;9C;9D;9E;9F;A0;A1;A2;A3;A4;A5;A6;A7;A8;A9;AA;AB;AC;AD;AE;AF;B0;B1;B2;B3;B4;B5;B6;B7;B8;B9;BA;BB;BC;BD;BE;BF;C0;C1;C2;C3;C4;C5;C6;C7;C8;C9;CA;CB;CC;CD;CE;CF;D0;D1;D2;D3;D4;D5;D6;D7;D8;D9;DA;DB;DC;DD;DE;DF;E0;E1;E2;E3;E4;E5;E6;E7;E8;E9;EA;EB;EC;ED;EE;EF;F0;F1;F2;F3;F4;F5;F6;F7;F8;F9;FA;FB;FC;FD;FE;FF;
Regarding output to a text file, just use the shell redirection operator:
关于输出到文本文件,只需使用 shell 重定向运算符:
$./hex-range.sh 91 FF > output.txt
回答by Dave
I'm almost there having picked through some simple commands and cobbled a very simple script together that pads properly and creates exactly the output I need:
我几乎已经完成了一些简单的命令并将一个非常简单的脚本拼凑在一起,该脚本可以正确填充并创建我需要的输出:
#!/bin/sh
#Script to test for loop
i=10 #put start num in here
j=20 #put end num in here
for (( a=i ; a <= j; a++ ))
do
printf '&#x%05x;' "$a" >> output.txt
done
回答by Felipe Kühne
Late reply, but here we go. I was just trying to create a file containing a sequence of bytes ranging from 0 to 255. Here is what I've got:
迟到的回复,但我们走了。我只是想创建一个包含从 0 到 255 的字节序列的文件。这是我得到的:
for n in $(seq 0 255); do printf "\x$(echo "obase=16; $n" | bc)" >> seq.bin; done
It is now exactly what was asked, but one can easily figure out how to change the command to do that.
现在正是被问到的,但是人们可以很容易地弄清楚如何更改命令来做到这一点。
Hope it helps.
希望能帮助到你。
回答by Danek Duvall
Here's another implementation, which doesn't take all the original constraints into account (namely the zero padding and the semicolon separator), but might be useful to someone nevertheless:
这是另一个实现,它没有考虑所有原始约束(即零填充和分号分隔符),但可能对某些人有用:
bc <<< "obase=16; ibase=16; for (i = $low; i <= $high ; i++) i"
It avoids a separate fork by using a here-string (though even the more portable version of piping the string to bcisn't too bad), and then lets bcdo all the computation and conversion. You can remove ibase=16to allow for decimal inputs (and you can set obaseto something else to have octal or binary or whatever).
它通过使用 here-string 避免了单独的分叉(尽管即使是更便携的将字符串管道化的版本bc也不错),然后让我们bc进行所有的计算和转换。您可以删除ibase=16以允许十进制输入(并且您可以设置obase为其他内容以具有八进制或二进制或其他内容)。
Ideally, I think, this would all be built in to seq, though the documentation for the GNU version suggests that they'd rather you do it yourself:
理想情况下,我认为,这将全部内置到 中seq,尽管 GNU 版本的文档表明他们宁愿您自己做:
If you want hexadecimal integer output, you can use printf to perform the conversion:
$ printf '%x\n' $(seq 1048575 1024 1050623)
fffff
1003ff
1007ff
如果需要十六进制整数输出,可以使用 printf 进行转换:
$ printf '%x\n' $(seq 1048575 1024 1050623)
fffff
1003ff
1007ff

