Bash의 변수로 정의 된 범위의 숫자를 어떻게 반복합니까?


1542

변수에 범위가 주어지면 Bash에서 숫자 범위를 어떻게 반복합니까?

이 작업을 수행 할 수 있음을 알고 있습니다 (Bash 설명서 에서 "시퀀스 표현"이라고 함 ).

 for i in {1..5}; do echo $i; done

다음을 제공합니다.

1
2
3
4
5

그러나 범위 끝점 중 하나를 변수로 바꾸려면 어떻게해야합니까? 작동하지 않습니다.

END=5
for i in {1..$END}; do echo $i; done

어떤 지문 :

{1..5}


26
안녕하십니까, 여기에서 읽은 정보와 힌트가 모두 도움이됩니다. seq를 사용하지 않는 것이 가장 좋습니다. 그 이유는 일부 스크립트는 이식 가능해야하며 일부 명령이 없을 수있는 다양한 유닉스 시스템에서 실행해야하기 때문입니다. 예를 들어 seBSD는 기본적으로 FreeBSD 시스템에는 없습니다.


9
Bash의 어떤 버전부터 정확하게 기억 나지 않지만이 명령은 후행 0도 지원합니다. 때로는 정말 도움이됩니다. 명령 for i in {01..10}; do echo $i; done은와 같은 숫자를 제공합니다 01, 02, 03, ..., 10.
topr

1
배열 의 인덱스 범위를 반복하려고하는 나와 같은 사람들에게는 bash 방법은 다음과 같습니다 myarray=('a' 'b' 'c'); for i in ${!myarray[@]}; do echo $i; done(느낌표에 유의하십시오). 원래 질문보다 구체적이지만 도움이 될 수 있습니다. bash 매개 변수 확장
PlasmaBinturong

1
중괄호 확장은 {jpg,png,gif}여기에서 직접 다루지 않는 것과 같은 표현식에도 사용 되지만 답은 동일합니다. 변수가있는 브레이스 확장을 참조하십시오 . [중복] 이 중 중복으로 표시됩니다.
tripleee

답변:


1742
for i in $(seq 1 $END); do echo $i; done

편집 : seq실제로 기억할 수 있기 때문에 다른 방법을 선호 합니다.)


36
seq는 일반적으로 속도가 느려지는 외부 명령의 실행을 포함합니다. 이것은 중요하지 않지만 많은 데이터를 처리하는 스크립트를 작성하는 경우 중요합니다.
paxdiablo

37
하나의 라이너로도 충분합니다. Pax의 솔루션도 훌륭하지만 성능이 실제로 염려된다면 쉘 스크립트를 사용하지 않을 것입니다.
eschercycle 2018 년

17
숫자를 생성하기 위해 seq가 한 번만 호출됩니다. exec () 'ing이 루프가 다른 단단한 루프 안에 있지 않으면 중요하지 않아야합니다.
Javier

29
외부 명령은 실제로 관련이 없습니다 : 외부 명령을 실행하는 오버 헤드가 걱정된다면 쉘 스크립트를 전혀 사용하고 싶지 않지만 일반적으로 유닉스에서는 오버 헤드가 낮습니다. 그러나 END가 높으면 메모리 사용량 문제가 있습니다.
Mark Baker

18
참고 seq $END기본은 1.에서 시작하는 것입니다으로, 충분 man seq"FIRST 또는 INCREMENT가 생략되면, 디폴트는 1".
fedorqui 'SO 중지 피해'

469

seq방법이 가장 간단하지만 Bash에는 내장 된 산술 평가 기능이 있습니다.

END=5
for ((i=1;i<=END;i++)); do
    echo $i
done
# ==> outputs 1 2 3 4 5 on separate lines

for ((expr1;expr2;expr3));구문은 for (expr1;expr2;expr3)C 및 유사한 언어에서와 마찬가지로 작동하며 다른 ((expr))경우 와 마찬가지로 Bash는이를 산술로 처리합니다.


67
이 방법은 큰 목록의 메모리 오버 헤드와에 대한 종속성을 피 seq합니다. 사용해!
bobbogo

3
@MarinSagovac이 수행 작업을하고 어떤 구문 오류가 없습니다. 쉘이 Bash인지 확실합니까?
gniourf_gniourf

3
@MarinSagovac #!/bin/bash스크립트의 첫 줄을 작성하십시오. wiki.ubuntu.com/…
Melebius

6
그것에 대한 아주 짧은 질문 : 왜 ((i = 1; i <= END; i ++)) 그리고 NOT ((i = 1; i <= $ END; i ++)); 왜 END 전에 $가 없습니까?
Baedsch

5
@Baedsch : 같은 이유로 나는 $ i로 사용되지 않습니다. 산술 평가를위한 bash 매뉴얼 페이지 상태 : "표현식 내에서, 변수 확장 구문을 사용하지 않고 쉘 변수를 이름으로 참조 할 수도 있습니다."
user3188140

192

토론

seqJiaaro가 제안한대로 사용하는 것이 좋습니다. Pax Diablo는 하위 프로세스 호출을 피하기 위해 Bash 루프를 제안했으며 $ END가 너무 큰 경우 메모리 친화적 인 이점이 있습니다. Zathrus는 루프 구현에서 일반적인 버그를 발견했으며 i텍스트 변수 이기 때문에 연관된 숫자로 연속 변환을 수행 한다는 것을 암시했습니다 .

정수 산술

이것은 Bash 루프의 개선 된 버전입니다.

typeset -i i END
let END=5 i=1
while ((i<=END)); do
    echo $i
    
    let i++
done

우리가 원하는 유일한 것이 있다면, echo우리는 쓸 수 echo $((i++))있습니다.

대변인 은 나에게 무언가를 가르쳤다 : 배쉬는 for ((expr;expr;expr))구조물을 허용한다 . Bash에 대한 전체 매뉴얼 페이지를 읽지 못했기 때문에 (Korn shell ( ksh) 매뉴얼 페이지를 사용하여 오래 전에했듯이) 그리워했습니다.

그래서,

typeset -i i END # Let's be explicit
for ((i=1;i<=END;++i)); do echo $i; done

seq아마도 가장 빠르지는 않지만 메모리를 효율적으로 사용하는 방법으로 보입니다 ( 출력 을 소비하기 위해 메모리를 할당 할 필요는 없습니다 .

초기 질문

eschercycle은 { a .. b } Bash 표기법은 리터럴에서만 작동합니다. Bash 매뉴얼에 따라 true입니다. 하나 하나의 (내부)이 장애물을 극복 할 수 fork()없이를 exec()(호출의 경우와 같이 seq다른 화상 되 포크 + 간부를 요구하는가) :

for i in $(eval echo "{1..$END}"); do

모두 evalecho배시 내장 매크로는하지만,이 fork()명령 교체합니다 (필요 $(…)구조체).


1
C 스타일 루프의 유일한 단점은 "$"로 시작하는 명령 행 인수를 사용할 수 없다는 것입니다.
karatedog

3
@ karatedog : for ((i=$1;i<=$2;++i)); do echo $i; donebash v.4.1.9에서 스크립트가 제대로 작동하므로 명령 줄 인수에 문제가 없습니다. 다른 의미가 있습니까?
tzot

eval 솔루션은 C와 같은 것보다 빠릅니다. $ (for (i = 1; i <= 100000; ++ i)); 하다 :; $ (eval echo "{1..100000}")에서 i에 대한 실제 0m21.220s 사용자 0m19.763s sys 0m1.203s $ 시간 완료; 하다 :; 끝난; 실제 0m13.881s 사용자 0m13.536s sys 0m0.152s
Marcin Zaluski

3
예, 그러나 평가는 악합니다 ... @MarcinZaluski time for i in $(seq 100000); do :; done가 훨씬 빠릅니다!
F. Hauri

eval 버전이 내 컴퓨터에서 가장 빠르기 때문에 성능은 플랫폼마다 다릅니다.
Andrew Prock

103

원래 표현이 효과가없는 이유는 다음과 같습니다.

에서 남자 bash는 :

중괄호 확장은 다른 확장보다 먼저 수행되며 다른 확장에 특수한 문자는 결과에 유지됩니다. 엄격하게 텍스트입니다. Bash는 확장 컨텍스트 또는 중괄호 사이의 텍스트에 구문 적 해석을 적용하지 않습니다.

따라서 중괄호 확장매개 변수 확장 전에 순수 텍스트 매크로 작업으로 초기에 수행되는 작업 입니다.

쉘은 매크로 프로세서와보다 공식적인 프로그래밍 언어 사이에서 고도로 최적화 된 하이브리드입니다. 일반적인 사용 사례를 최적화하기 위해 언어가 다소 복잡해지고 일부 제한이 허용됩니다.

추천

Posix 1 기능을 고수하는 것이 좋습니다 . 이는 for i in <list>; do목록이 이미 알려진 경우을 사용하는 것을 의미합니다 . 그렇지 않으면 다음 과 같이 while또는을 사용하십시오 seq.

#!/bin/sh

limit=4

i=1; while [ $i -le $limit ]; do
  echo $i
  i=$(($i + 1))
done
# Or -----------------------
for i in $(seq 1 $limit); do
  echo $i
done


1. Bash는 훌륭한 쉘이며 대화식으로 사용하지만 스크립트에 bash-ism을 넣지 않습니다. 스크립트는 더 빠른 쉘,보다 안전한 쉘, 임베디드 스타일의 스크립트가 필요할 수 있습니다. / bin / sh로 설치된 모든 항목에서 실행해야 할 수 있으며 일반적인 프로 표준 인수가 모두 있습니다. 쉘 쇼크 ( 일명 bashdoor)를 기억 하십니까?


13
나는 힘을 가지고 있지 않지만 모든 배쉬 배꼽을 뛰어 넘지 만 루프와 산술 평가를 위해 C 스타일 직후에 목록을 약간 위로 움직일 것입니다.
mateor

2
의미는 중괄호 확장이 seq넓은 범위 에 비해 많은 메모리를 절약하지 못한다 는 것입니다. 예를 들어, echo {1..1000000} | wc에코는 1 줄, 백만 단어 및 6,888,896 바이트를 생성합니다. 시도 seq 1 1000000 | wc하면 백만 줄, 백만 단어 및 6,888,896 바이트가 생성되며 time명령 으로 측정 할 때 7 배 이상 빠릅니다 .
George

참고 : 나는 POSIX의 언급 한 while내 대답에 이전 방법 : stackoverflow.com/a/31365662/895245 그러나 다행 당신은 :-) 동의
치로 틸리가冠状病毒审查六四事件法轮功

이 답변을 아래의 성능 비교 답변에 포함 시켰습니다. stackoverflow.com/a/54770805/117471는 (이것은 내가 할 남아있는 어떤 것들 추적 할 자신에 메모입니다.)
브루노 Bronosky

@mateor 루프와 산술 평가를위한 C 스타일은 같은 솔루션이라고 생각했습니다. 뭔가 빠졌습니까?
오스카 장

71

POSIX 방식

이식성에 관심이 있다면 POSIX 표준예제를 사용하십시오 .

i=2
end=5
while [ $i -le $end ]; do
    echo $i
    i=$(($i+1))
done

산출:

2
3
4
5

POSIX 가 아닌 것 :


이 답변에 대한 4 개의 공감대가 있었는데 이는 매우 드문 일입니다. 이것이 링크 통합 웹 사이트에 게시 된 경우, 링크를주세요.
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功

인용 부호는 x전체 표현식 이 아니라을 나타냅니다 . $((x + 1))괜찮습니다.
chepner

이식성이없고 GNU와 다르지만 seq(BSD seq에서는으로 시퀀스 종료 문자열을 설정할 수 있음 -t) FreeBSD와 NetBSD는 seq각각 9.0과 3.0 이후로 사용됩니다.
Adrian Günter

@CiroSantilli @chepner $((x+1))$((x + 1))구문 분석 정확히 같은, 파서가 토큰 화 때와 x+1는 3 토큰으로 분할 될 것입니다 : x, +,와 1. x유효한 숫자 토큰은 아니지만 유효한 변수 이름 토큰이지만 x+분할되지 않습니다. +는 유효한 산술 연산자 토큰이지만 아직 +1토큰이 아니므로 토큰이 다시 분할됩니다. 기타 등등.
Adrian Günter

이 답변을 아래의 성능 비교 답변에 포함 시켰습니다. stackoverflow.com/a/54770805/117471는 (이것은 내가 할 남아있는 어떤 것들 추적 할 자신에 메모입니다.)
브루노 Bronosky

35

간접적 인 또 다른 계층 :

for i in $(eval echo {1..$END}); do
    

2
+1 : 또한 'valid for {1 ..'$ END '}; do ... 'eval 은이 문제를 해결하는 자연스러운 방법 인 것 같습니다.
윌리엄 Pursell

28

당신이 사용할 수있는

for i in $(seq $END); do echo $i; done

seq는 일반적으로 속도가 느려지는 외부 명령의 실행을 포함합니다.
paxdiablo

9
각 반복에 대해 외부 명령을 한 번만 실행하지는 않습니다. 하나의 외부 명령을 실행하는 데 문제가있는 경우 잘못된 언어를 사용하고있는 것입니다.
Mark Baker

1
그렇다면 이것이 중요한 유일한 중첩입니까? 성능 차이가 있거나 미지의 기술적 부작용이 있는지 궁금합니다.
Sqeaky

@Squeaky 그것은 여기에 답변 된 별도의 질문입니다. stackoverflow.com/questions/4708549/…
tripleee

이 답변을 아래의 성능 비교 답변에 포함 시켰습니다. stackoverflow.com/a/54770805/117471는 (이것은 내가 할 남아있는 어떤 것들 추적 할 자신에 메모입니다.)
브루노 Bronosky

21

당신이 이것을 좋아할 것보다 접두사가 필요하다면

 for ((i=7;i<=12;i++)); do echo `printf "%2.0d\n" $i |sed "s/ /0/"`;done

그 결과

07
08
09
10
11
12

4
printf "%02d\n" $i보다 쉽지 않을까요 printf "%2.0d\n" $i |sed "s/ /0/"?
zb226

19

BSD / OS X를 사용하는 경우 seq 대신 jot를 사용할 수 있습니다.

for i in $(jot $END); do echo $i; done

17

이것은 다음에서 잘 작동합니다 bash.

END=5
i=1 ; while [[ $i -le $END ]] ; do
    echo $i
    ((i = i + 1))
done

6
echo $((i++))작동하고 한 줄에 결합합니다.
Bruno Bronosky

1
불필요한 bash 확장이 있습니다. POSIX 버전 : stackoverflow.com/a/31365662/895245
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功

1
@Ciro는 질문에 구체적으로 bash가 있고 bash 태그가 있기 때문에 bash 'extensions'가 괜찮은 것 이상이라고 생각할 것입니다 :-)
paxdiablo

@paxdiablo 나는 그것이 정확하지 않다는 것을 의미하지는 않습니다. 그러나 우리가 할 수있을 때 왜 휴대용이
아닌지

에서 bash, 우리는 간단히 while [[ i++ -le "$END" ]]; do테스트에서 (포스트-) 증가를 수행 할 수 있습니다
Aaron McDaid

14

여기에 몇 가지 아이디어를 결합하고 성능을 측정했습니다.

TL; DR 테이크 아웃 :

  1. seq{..}정말 빠르다
  2. for그리고 while루프는 느린
  3. $( ) 느리다
  4. for (( ; ; )) 루프가 느리다
  5. $(( )) 더 느리다
  6. 메모리에서 N 개의 숫자 (seq 또는 {..})를 걱정하는 것은 어리석은 일입니다 (적어도 최대 1 백만).

이것은 결론 이 아닙니다 . 결론을 내리려면 각각의 코드 뒤에있는 C 코드를 살펴 봐야합니다. 이것은 우리가 코드를 반복하기 위해 이러한 각 메커니즘을 사용하는 방법에 대한 것입니다. 대부분의 단일 작업은 대부분의 경우 중요하지 않은 속도와 같은 속도에 가깝습니다. 그러나 같은 메커니즘 for (( i=1; i<=1000000; i++ ))은 시각적으로 볼 수있는 많은 작업입니다. 또한 루프 에서 얻는 것보다 훨씬 많은 연산 이 있습니다 for i in $(seq 1 1000000). 그리고 그것은 당신에게 분명하지 않을 수 있습니다, 그래서 이런 테스트를하는 것이 가치있는 이유입니다.

시민

# show that seq is fast
$ time (seq 1 1000000 | wc)
 1000000 1000000 6888894

real    0m0.227s
user    0m0.239s
sys     0m0.008s

# show that {..} is fast
$ time (echo {1..1000000} | wc)
       1 1000000 6888896

real    0m1.778s
user    0m1.735s
sys     0m0.072s

# Show that for loops (even with a : noop) are slow
$ time (for i in {1..1000000} ; do :; done | wc)
       0       0       0

real    0m3.642s
user    0m3.582s
sys 0m0.057s

# show that echo is slow
$ time (for i in {1..1000000} ; do echo $i; done | wc)
 1000000 1000000 6888896

real    0m7.480s
user    0m6.803s
sys     0m2.580s

$ time (for i in $(seq 1 1000000) ; do echo $i; done | wc)
 1000000 1000000 6888894

real    0m7.029s
user    0m6.335s
sys     0m2.666s

# show that C-style for loops are slower
$ time (for (( i=1; i<=1000000; i++ )) ; do echo $i; done | wc)
 1000000 1000000 6888896

real    0m12.391s
user    0m11.069s
sys     0m3.437s

# show that arithmetic expansion is even slower
$ time (i=1; e=1000000; while [ $i -le $e ]; do echo $i; i=$(($i+1)); done | wc)
 1000000 1000000 6888896

real    0m19.696s
user    0m18.017s
sys     0m3.806s

$ time (i=1; e=1000000; while [ $i -le $e ]; do echo $i; ((i=i+1)); done | wc)
 1000000 1000000 6888896

real    0m18.629s
user    0m16.843s
sys     0m3.936s

$ time (i=1; e=1000000; while [ $i -le $e ]; do echo $((i++)); done | wc)
 1000000 1000000 6888896

real    0m17.012s
user    0m15.319s
sys     0m3.906s

# even a noop is slow
$ time (i=1; e=1000000; while [ $((i++)) -le $e ]; do :; done | wc)
       0       0       0

real    0m12.679s
user    0m11.658s
sys 0m1.004s

1
좋은! 그래도 요약에 동의하지 마십시오. 나에게 $(seq)속도가 같은 속도 인 것 같습니다 {a..b}. 또한 각 작업에는 거의 같은 시간이 걸리므로 루프의 각 반복에 약 4μs가 추가됩니다. 여기서 연산은 신체 의 반향 , 산술 비교, 증분 등입니다. 놀라운 것이 있습니까? 누가 루프 관련 도구를 사용하여 작업을 수행하는 데 걸리는 시간을 중요하게 생각합니다. 런타임은 루프의 내용에 의해 지배 될 수 있습니다.
bobbogo

@bobbogo 당신이 맞아요, 그것은 실제로 작업 수에 관한 것입니다. 이것을 반영하여 답변을 업데이트했습니다. 실제로 많은 전화가 예상보다 많은 작업을 수행합니다. 나는 내가 실행 한 약 50 가지 테스트 목록에서이를 좁혔습니다. 나는이 연구에도 불구하고 나의 연구가 너무 나빴을 것으로 예상했다. 항상 그렇듯이 코딩 작업의 우선 순위를 다음과 같이 지정하는 것이 좋습니다. 읽을 수있게하십시오. 더 빨리 만드십시오. 휴대용으로 만드십시오. 종종 # 1이 # 3을 유발합니다. 당신이해야 할 때까지 # 4에 시간을 낭비하지 마십시오.
브루노 Bronosky

8

나는이 질문에 관한 bash것이지만, 단지 기록을 위해- ksh93더 똑똑하고 예상대로 구현합니다.

$ ksh -c 'i=5; for x in {1..$i}; do echo "$x"; done'
1
2
3
4
5
$ ksh -c 'echo $KSH_VERSION'
Version JM 93u+ 2012-02-29

$ bash -c 'i=5; for x in {1..$i}; do echo "$x"; done'
{1..5}

8

이것은 다른 방법입니다.

end=5
for i in $(bash -c "echo {1..${end}}"); do echo $i; done

1
이것은 다른 쉘을 생성하는 오버 헤드가 있습니다.
codeforester 2018 년

1
실제로 이것은 1 개면 충분할 때 2 개의 껍데기를 생성하기 때문에 매우 끔찍합니다.
브루노 Bronosky

8

brace-expression 구문에 최대한 가깝게 유지하려면 rangebash-tricks '에서 함수를range.bash 시도하십시오 .

예를 들어, 다음은 모두 정확히 동일한 작업을 수행합니다 echo {1..10}.

source range.bash
one=1
ten=10

range {$one..$ten}
range $one $ten
range {1..$ten}
range {1..10}

가능한 한 "gotchas"가 적은 네이티브 bash 구문을 지원하려고 시도합니다. 변수가 지원 for i in {1..a}; do echo $i; done될뿐만 아니라 문자열 (예 :)로 제공되는 유효하지 않은 범위의 종종 원하지 않는 동작 도 방지됩니다.

다른 답변은 대부분의 경우 작동하지만 모두 다음과 같은 단점 중 하나 이상이 있습니다.

  • 그들 중 많은 사람들이 사용하는 서브 쉘 수, 성능을 해칠가능하지 않을 수 일부 시스템을.
  • 그들 중 많은 사람들이 외부 프로그램에 의존합니다. 심지어 seqbash에 의해로드해야합니다, 사용할 수 있도록 설치해야하며,이 경우 작업에 들어, 당신이 기대하는 프로그램을 포함해야 바이너리입니다. 유비쿼터스 여부에 관계없이 Bash 언어 자체보다 훨씬 더 많은 것을 의지합니다.
  • @ephemient와 같이 고유 Bash 기능 만 사용하는 솔루션은 다음과 같은 알파벳 범위에서는 작동하지 않습니다 {a..z}. 버팀대 확장됩니다. 문제는 숫자의 범위에 관한 것이 었습니다 .
  • 대부분은 {1..10}괄호 확장 범위 구문 과 시각적으로 유사하지 않으므로 둘 다 사용하는 프로그램은 읽기가 조금 더 어려울 수 있습니다.
  • @bobbogo의 대답은 익숙한 구문 중 일부를 사용하지만 $END변수가 범위의 다른쪽에 유효한 범위 "bookend"가 아닌 경우 예기치 않은 작업 을 수행합니다. 경우 END=a, 예를 들어, 오류가 발생되지 않고 그대로 값이 {1..a}에코됩니다. 이것은 Bash의 기본 동작이기도합니다. 종종 예상치 못한 일입니다.

면책 조항 : 나는 링크 코드의 저자입니다.



6

이것들은 모두 훌륭하지만 seq는 더 이상 사용되지 않으며 대부분 숫자 범위에서만 작동합니다.

for 루프를 큰 따옴표로 묶으면 문자열을 반향 할 때 시작 및 끝 변수가 역 참조되며 문자열을 BASH로 다시 보내서 실행할 수 있습니다. $i\를 사용하여 이스케이프해야하므로 서브 쉘로 전송되기 전에 평가되지 않습니다.

RANGE_START=a
RANGE_END=z
echo -e "for i in {$RANGE_START..$RANGE_END}; do echo \\${i}; done" | bash

이 출력은 변수에 할당 될 수도 있습니다 :

VAR=`echo -e "for i in {$RANGE_START..$RANGE_END}; do echo \\${i}; done" | bash`

이것이 생성해야하는 유일한 "오버 헤드"는 bash의 두 번째 인스턴스 여야하므로 집중적 인 작업에 적합해야합니다.


5

쉘 명령을 수행하고 있고 (I와 같은) 파이프 라이닝을 위해 페티쉬를 가지고 있다면, 이것은 좋습니다.

seq 1 $END | xargs -I {} echo {}


3

이 작업을 수행하는 방법에는 여러 가지가 있지만 내가 선호하는 방법은 다음과 같습니다.

사용 seq

시놉시스 man seq

$ seq [-w] [-f format] [-s string] [-t string] [first [incr]] last

통사론

전체 명령
seq first incr last

  • 첫 번째는 순서의 시작 번호입니다 (기본적으로 선택 사항입니다).
  • incr은 증분입니다 [기본적으로 선택 사항입니다] :
  • last는 시퀀스의 마지막 숫자입니다

예:

$ seq 1 2 10
1 3 5 7 9

처음과 마지막으로 만 :

$ seq 1 5
1 2 3 4 5

마지막으로 만 :

$ seq 5
1 2 3 4 5

사용 {first..last..incr}

여기서 첫 번째와 마지막은 필수이며 incr은 선택 사항입니다.

처음과 마지막 만 사용

$ echo {1..5}
1 2 3 4 5

incr 사용

$ echo {1..10..2}
1 3 5 7 9

아래와 같은 문자에도 사용할 수 있습니다

$ echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z

3

' seq'또는 ' eval' jot또는 산술 확장 형식을 사용하고 싶지 않은 경우 . for ((i=1;i<=END;i++))또는 다른 루프 예. while, ' printf'하고 행복하다 echo'만 원하지 않는다면 이 간단한 해결 방법이 예산에 맞을 수 있습니다.

a=1; b=5; d='for i in {'$a'..'$b'}; do echo -n "$i"; done;' echo "$d" | bash

추신 : seq어쨌든 내 배쉬에는 ' '명령 이 없습니다 .

Mac OSX 10.6.8, Bash 3.2.48에서 테스트


0

이것은 Bash와 Korn에서 작동하며 높은 숫자에서 낮은 숫자로 갈 수 있습니다. 아마도 가장 빠르거나 예쁘지는 않지만 충분히 잘 작동합니다. 네거티브도 처리합니다.

function num_range {
   # Return a range of whole numbers from beginning value to ending value.
   # >>> num_range start end
   # start: Whole number to start with.
   # end: Whole number to end with.
   typeset s e v
   s=${1}
   e=${2}
   if (( ${e} >= ${s} )); then
      v=${s}
      while (( ${v} <= ${e} )); do
         echo ${v}
         ((v=v+1))
      done
   elif (( ${e} < ${s} )); then
      v=${s}
      while (( ${v} >= ${e} )); do
         echo ${v}
         ((v=v-1))
      done
   fi
}

function test_num_range {
   num_range 1 3 | egrep "1|2|3" | assert_lc 3
   num_range 1 3 | head -1 | assert_eq 1
   num_range -1 1 | head -1 | assert_eq "-1"
   num_range 3 1 | egrep "1|2|3" | assert_lc 3
   num_range 3 1 | head -1 | assert_eq 3
   num_range 1 -1 | tail -1 | assert_eq "-1"
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.