변수로 범위가 지정된 경우 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}
가장 간단한 방법은 '시퀀스' 를 기본으로 하지만, 배시 산술 평가.
END=5
for ((i=1;i<=END;i++)); do
echo $i
done
# ==> outputs 1 2 3 4 5 on separate lines
이 '에 대해 ((, expr1 expr2 expr3),' 처럼 '에 대해 chunghwa 작동됨 (, expr1 expr2 expr3)' 가 C 와 비슷한 ' ((식)' 같은 건 다른 언어, 산술, 배시 취급합니다.
'괜찮아' 는 등 사용하여 시퀀스 자라로 제안했다. Pax 디아블로 등을 피하기 위해 더 많은 메모리를 활용할 수 있는 하위 호출하십시오 Bash 루프, 추가 친화적임 기술입니까 경우 $ 끝이 너무 큽니다. 또한 일반적인 버그 눈에 사토러스 루프의 구축, 이후 'i' 는 텍스트 변수, 지속적인 변환에는 시사했다 이리저리 숫자임 수행합니까 연관된 천천히 해.
이는 개선된 버전의 Bash 루프:
typeset -i i END
let END=5 i=1
while ((i<=END)); do
echo $i
…
let i++
done
만약 우리가 원하는 '에코' 는 우리가 할 수 있는 유일한 심아이엔큐 관심용 쓰기 '에코 $ ((i++)'.
[에프미언스] [1] 뭔가 나를 가르쳤다. 배시 (식, 식, 식) '를 통해' 구문. 이후, ve never 검토완료 I& # 39 의 전체 맨페이지를 배시 (그것을비유하사 I& # 39, ve done 함께 콘 셸 ('ksh'), 그리고 정말 오래전 일이지를 맨페이지를), 내가 그걸 놓쳤다.
그래서,
typeset -i i END # Let's be explicit
for ((i=1;i<=END;++i)); do echo $i; done
대부분의 효율적인 메모리 운행에서어떠한 것으로 보인다 (이 won& # 39, t be 필요한 메모리를 할당지 소비할 수 '시퀀스' & # 39 의 출력입니다 경우 매우 큰 문제가 될 수 있는 최종) 이 아닐 수 있지만 "빠른".
배시 (bash 리터럴 표기법을} {a.b 미디어만을 사용하여 작동됨 셔키클레 것으로 알고 있다고 말했다. 이에 따라 true to the Bash 수작업식. 이를 극복할 수 있는 하나의 장애물은 하나의 (내부) ' ()' 없이 '포크하지 exec ()' 으로 경우. 호출하십시오 다른 이미지 '를 통해' 시퀀스 필요합니다 기술입니까 fork+exec):
for i in $(eval echo "{1..$END}"); do
모두 '평가' 와 '에코' 이 아니라 ' ()' 가 필요한 명령을 Bash 기본 제공 포크하지 대체 ($ (.) '이' chunghwa).
[1]: https://stackoverflow.com/questions/169511/how-do-i-iterate-over-a-range-of-numbers-in-bash # 171041
이 때문에 당초 표현식에서는 didn& # 39, 빗나갔다.
>. 중괄호 확대가 전에 수행됨 >. 다른 모든 확장 및 기타 >. 다른 특수 문자 >. 확장 보존됩니다 >. 결과. 이는 엄격하게 출력본. 배시 >. 통사 적용하지 않는다. >. 맥락에 대한 해석 >. 확장 또는 사이에 텍스트를 >. 중괄호.
그래서 매크로 확장 , , 작업 참여를 수행됨 순수한 출력본 expansion. 매개변수입니다 초 전에 뭔가 특별한 게 있다
포탄 최적화된 하이브리드 매크로 프로그래밍 언어 간의 공식 프로세서및 있다. 일반적인 활용 사례, 언어는 브라운아저씨의 최적화하려면 오히려 더 복잡하고 일부 한계에는 사용할 수 있습니다.
>. 권장안을
꼭 이래야겠어요 제안하세요 Posix< sup> 1< /sup>,, 선호하는 편입니다. 피쳐들입니다. 즉, 내가 사용하는 '에서 list> <;; 이 목록은 동시에 사용할 경우, 그렇지 않으면 이미 알려진 못하며창조된 ',' 같이 ',' 또는 '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
< hr>; sup> <; 1. 하지만 나는 그것을 사용하는 것은 큰 배시 셸을 통해 쉐퍼드도 don& # 39 로, t 동일팔레트에 ism 배시 내 스크립트입니다. 셸 스크립트를 하나, 더 빠르게, 보다 안전한 포함된 스타일 한 할 수 있습니다. 그들이 할 수 있는 실행하십시오 있는모든 / bin / sh 로 설치한 후 일반적인 pro 표준 인수만 모두 있습니다. , , 바하두르 가능 lc-fc 너희에게베풀어진 셸쇼크 < /sup>.
신경습니까 사용할 경우 약 포터블식, [예 &solarisdvd POSIX 표준] (http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html # tag_18_06_04_01):
i=2
end=5
while [ $i -le $end ]; do
echo $i
i=$(($i+1))
done
출력:
2
3
4
5
'-' (()) 는 공통 확장명은 않고 있지만 달러, [언급한 바와 같이 POSIX 에 의해 자체가] (http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html # tag_18_09_04).
>. 셸 변수 x 가 유효한 정수 값을 형성하는 경우, 필요한 경우, 다음 등 주요 상수입니다 + 또는 - 예중이 확장 " ", 산술, $ ((x)) $ ($ x)) 및 " "; 반품해야 불지옥으 동일한 값을.
하지만 말 그대로 '$ 판독값 않는 것이 있다는 것을 의미한다 (x + 1))' 이후 '1' 은 변수 x + 확장됨 아닙니다.
여기에 몇 가지 아이디어를 i& # 39, ve 결합됨 측정했습니다 성능.
정말 빠른.} {'이' 시퀀스 '와' 1.
# 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
이 질문은 '약', 배시 그러니까말이야 애디슨에게 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}
스케쳐내 최대한 가깝게 중괄호 표현식에서는 유지할 수 있는 [',' 기능은 # 39 에서 bash-tricks& maxvalorarray 시도하시겠습니까 아웃해야 구문, '치역.바시'] (https://github.com/zbentley/bash-tricks/tree/master/range).
예를 들어, 다음과 같은 모든 할 것처럼 똑같이 '에코'} {1.10:
source range.bash
one=1
ten=10
range {$one..$ten}
range $one $ten
range {1..$ten}
range {1..10}
배시 (bash, 구문 로 몇 " gotchas" 넷윈을 지원하기 위해 시도합니다. 수 있다. 그러나 바람직하지 않은 경우가 많습니다. 비헤이비어를 지원, 변수가 아니라 잘못된 범위를 공급되고 있다 (예를 들어 '에서 {}, 내가 1.a 문장열 echo $ i do. 수행되 ') 는 충분히 잘 알려져 있다.
대부분의 경우, 그들은 모두 다른 의견은 작동합니까 적어도 다음 중 하나가 단점:
그들 중 많은 사용 - [서브셸스] (http://tldp.org/LDP/abs/html/subshells.html), (http://rus.har.mn/blog/2010-07-05/subshells/) 수 있는 [피해를 성능] 및 [불가능할 수 있습니다] (https://superuser.com/questions/559709/how-to-change-the-maximum-number-of-fork-process-by-user-in-linux) 에서 일부 시스템.
부인: 나는 작성자입니다 링크됨 코드입니다.
그러나 이들은 모두 시퀀스 () 는 아마도 가장 잘 사용되지 않으며 미디어만을 작동합니까 숫자 범위.
For 루프는 큰따옴표로 너회의 묶으십시오 경우, 시작과 종료 될 때 문자열을 string 출하됩니다 수 있습니다 다음 com/go/4e6b330a_kr 역참조되었습니다. 실행을 위해 오른쪽 다시 내주었다. i '와' $ # 39 의 \& 이스케이프할 필요가 있기 때문에 서브셸 보내는 전에 평가됩니다.
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`
유일한 " overhead"; 이렇게 하면 할 수 있도록 두 번째 인스턴스에서는 배시 발령합니다 적합하지 집약형에 작업을 한다.
방법에는 여러 가지가 있을 수 있지만, 내가 이렇게 수준들과 포지셔닝하십시오 아래와 같이 주어져 있다.
>. 시놉시스 (줄거리) '에서' 양반이군요 시퀀스
$ seq [-w] [-f format] [-s string] [-t string] [first [incr]] last
>. 문법
전체 command< br>; '마지막' 첫 incr 시퀀스
예:
$ seq 1 2 10
1 3 5 7 9
오로지 처음이자 마지막.
$ seq 1 5
1 2 3 4 5
오로지 성:
$ seq 5
1 2 3 4 5
여기서 첫 번째 및 마지막 필수인 incr 선택적입니다
그냥 사용한 첫 번째 및 마지막
$ echo {1..5}
1 2 3 4 5
사용하는 증분
$ 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
이 작품은 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"
}
'a = 1. b = 5. d = & # 39, & # 39 에서 {$ a& # 39, 내가 .& b& # 39$ # 39;};;; echo $ i" 못하며창조된 뻨을 ";; 수행되, & # 39. echo $ d" "; 배시 '
PS: & # 39, & # 39 없다 ',' 내 bash doesn& seq # 39. 명령을 겁니다.