쉘 괄호 확장에서 $ variable을 어떻게 사용합니까? $var inbash에서 범위와 함께

$var inbash에서 범위와 함께 쉘 괄호 확장 을 사용 하고 싶습니다 . 단순히 퍼팅 {$var1..$var2}이 작동하지 않아서 “측면”으로 갔다 …

다음은 효과가 있지만 약간 혼란입니다.

# remove the split files
echo rm foo.{$ext0..$extN} rm-segments > rm-segments
source rm-segments

더 “정상적인”방법이 있습니까?



답변

시도해 볼 수 있습니다 :

eval rm foo.{$ext0..$extN}

이것이 최선의 대답인지 확실하지 않지만 확실히 대답입니다.


답변

당신이 이미 실현으로, {1..3}로 확장 1 2 3하지만, {foo..bar}또는 {$foo..$bar}하지 트리거 중괄호 확장을, 후자는 이후 대체 확장 $foo하고 $bar그 값에 의해.

GNU (예 : 내장되지 않은 Linux)에 대한 폴 백이 seq명령입니다.

for x in `seq $ext0 $extN`; do rm foo.$x; done

또 다른 가능성. 경우 foo.에는 쉘 특수 문자를 포함하지이며,

rm `seq $ext0 $extN | sed 's/^/foo./'`

가장 간단한 해결책은 zsh를 사용 rm foo.{$ext0..$extN}하는 것입니다.


답변

다른 답변을 사용하여 논의하는 동안 evalseqbash, 당신은 전통적인 C 스타일 사용할 수 있습니다 for산술 상황에서 루프를. 변수 ext0와 변수 extN가 확장되어 ((..))정의 된 범위에 대해 루프가 실행됩니다.

for (( idx = ext0; idx <= extN; idx++ )); do
    [[ -f "$foo.$idx" ]] || { printf "file %s does not exist" "$foo.$idx" >&2 ; continue }
    rm "$foo.$idx"
done

최적의 방법을 찾고 여러 rm명령을 피하려면 임시 자리 표시자를 사용하여 파일 이름 결과를 저장하고 rm한 번에 호출 할 수 있습니다 .

 results=()
 for (( idx = ext0; idx <= extN; idx++ )); do
     [[ -f "$foo.$idx" ]] || { printf "file %s does not exist" "$foo.$idx" >&2 ; continue }
     results+=( "$foo.$idx" )
 done

이제 rm확장 배열 에서 명령을 호출하십시오.

 rm -- "${results[@]}"

답변

    function f_over_range {
        for i in $(eval echo {$1..$2}); do
            f $i
        done
    }

    function f {
        echo $1
    }

    f_over_range 0 5
    f_over_range 00 05

노트:

  • eval을 사용하면 명령 삽입 보안 위험이 노출됩니다
  • Linux는 “00 \ n01 \ n02..etc”를 인쇄하지만 OSX는 “1 \ n2 \ n … etc”를 인쇄합니다
  • 루프에 seq 또는 C 스타일을 사용하면 중괄호 확장의 선행 0 처리와 일치하지 않습니다.