바이너리 값을 포함하는 두 개의 bash 변수가 있다고 가정해 보겠습니다.
a=0011 # decimal 3
b=1000 # decimal 8
$a
가능한 모든 값을 반복 하여 $b
바이너리로 유지할 수 있는 방법이 있나요 ? 그것은 다음과 같습니다:
for blah in $(seq $a $b) ; do
print "Blah is: $blah"
done
따라서 다음과 같이 출력됩니다.
Blah is: 0011
Blah is: 0100
Blah is: 0101
Blah is: 0110
Blah is: 0111
Blah is: 1000
나는 시도했다:
for blah in $(seq "$((2#$a))" "$((2#$b))") ; do
하지만 $blah
10진수가 되고 2진수로 유지하고 싶습니다. (언제든지 10진수를 다시 2진수로 변환할 수 있지만 이미극심한바이너리)
코드는 제한된 Linux(오픈WRT) 사용할 수 없습니다 obase
. 대답이 이렇다면이진 값을 보존하는 것은 불가능합니다, 이것은 또한 유용한 답변입니다 ( 를 사용하지 않고 10진수를 2진수로 변환하는 함수를 만들 수 있습니다 obase
) 또한 일반 bash
.
답변1
당신은 이것에 꽤 가깝습니다 :
for blah in $(seq "$((2#$a))" "$((2#$b))") ; do
for
비슷한 방법을 사용하여 루프에서 10진수 값을 다시 2진수로 변환하면 됩니다 dc
.
예
$ for blah in $(seq "$((2#0011))" "$((2#1000))"); do \
printf "%04d\n" $(echo "obase=2;$blah" | bc);done
0011
0100
0101
0110
0111
1000
printf
앞에 0이 채워지고 특정 너비로 형식이 지정되도록 출력을 제어하는 데 사용됩니다 . 매개변수는 %04d
출력 내용을 지정합니다.
이 명령의 또 다른 핵심은 bc
명령줄 계산기를 사용하는 것입니다. 이 명령의 예는 다음과 같습니다.
echo "obase=2;$blah" | bc
를 사용하여 값을 가져와서 $blah
2진수(이진수라고도 함)로 변환합니다 bc
.
BC 또는 DC 없음
이러한 도구가 전혀 존재하지 않도록 제한된 시스템을 사용하는 경우 awk
매뉴얼에 있는 이 기능을 직접 사용하여 변환할 수 있습니다.awk
예
다음 내용으로 파일을 만들고 이름을 dec2bin.awk
.
# bits2str --- turn a byte into readable 1's and 0's
function bits2str(bits, data, mask)
{
if (bits == 0)
return "0"
mask = 1
for (; bits != 0; bits = rshift(bits, 1))
data = (and(bits, mask) ? "1" : "0") data
while ((length(data) % 8) != 0)
data = "0" data
return data
}
{
printf("%s\n", bits2str($1))
}
이제 위의 기능을 사용하십시오.
$ for blah in $(seq "$((2#0011))" "$((2#1000))"); do echo $blah \
| awk -f dec2bin.awk; done
00000011
00000100
00000101
00000110
00000111
00001000
답변2
seq
내장되어 있지 않습니다. 또한 Posix 표준의 일부도 아닙니다. 그러나 일반적인 구현에는 seq
10이 아닌 기준으로 정렬하는 기능이 없습니다.
Bash 에서는 범위 를 {start..finish}
.{a..f}
a b c d e f
내가 아는 한 이것은 몇 가지 가능성을 제공하는 간단한 시퀀스 생성기입니다.
어리석은 방법은 이진이 아닌 값을 필터링하는 것입니다. a
합계가 b
아주 작지는 않지만 매우 비효율적 이라면 이는 간단합니다.
for x in $(seq -w $a $b); do
if [[ ! ($x =~ [2-9]) ]]; then
echo $x
fi
done
이것이 더 나은 솔루션입니다. a
과 의 길이가 같다고 가정하면 b
(그렇지 않은 경우 printf를 사용하여 이 문제를 해결할 수 있음) 다음은 a에서 b(포함)까지의 모든 이진수를 반복합니다.
# We need a string of 0s at least as long as a:
z=${a//1/0}
while [[ ! ($a > $b) ]]; do
# do something with $a
# The following "increments" a by removing the last 0 (and trailing 1s)
# and replacing that with a 1 and the same number of 0s.
a=$(printf "%.*s" ${#a} ${a%0*}1$z)
done
답변3
다음을 사용하는 것이 더 쉽습니다 zsh
.
for ((i=2#$a; i<=2#$b; i++)) echo $(([##2]i))
또는 0 패딩을 사용하십시오.
for ((i=2#$a; i<=2#$b; i++)) printf '%04d\n' $(([##2]i))
그렇지 않으면 다음을 사용할 수 있습니다 bc
.
echo "ibase=obase=2; for (i=$a; i<=$b; i++) i" | bc
또는 dc
:
echo "2doi $a [p1+d$b!<a]dsax" | dc
0-pad의 경우 항상 출력을 다음으로 파이프할 수 있습니다.
sed 's/^/000/;s/^0*\(.\{4\}\)/\1/'
답변4
이 방법은 많은 처리를 수행하므로 대규모에는 적합하지 않습니다.
seq -f '%04g' 0011 1000 | grep -v '[2-9]'