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

모두 eval와 echo배시 내장 매크로는하지만,이 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.