$@ 첫 번째 매개변수 제외

$@ 첫 번째 매개변수 제외

다음과 같은 방식으로 실행되는 쉘 스크립트를 작성해야 합니다.

./myscript arg1 arg2_1 arg2_2 arg2_3 ....... arg2_#

스크립트에 for 루프가 있습니다.

for i in $@

그러나 내가 아는 한 $@에는 $1부터 $($#-1)까지 포함됩니다. 하지만 내 프로그램의 경우 $1은 $2 $3 $4 등과 크게 다릅니다. $2부터 끝까지 반복하고 싶습니다. 어떻게 해야 합니까? 감사합니다:)

답변1

첫째, $@따옴표가 없으면 의미가 없으므로 사용해서는 안 됩니다. 참조( ) 및 목록 컨텍스트 $@에서만 사용할 수 있습니다 ."$@"

for i in "$@"목록 컨텍스트에서 자격을 갖추었지만 여기서는 위치 인수를 반복하기 위해 표준적이고 가장 이식 가능하며 간단한 형식은 다음과 같습니다.

for i
do something with "$i"
done

이제 두 번째 요소부터 시작하여 요소를 반복하려면 표준적이고 가장 이식 가능한 방법은 다음을 사용하는 것입니다 shift.

first_arg=$1
shift # short for shift 1
for i
do something with "$i"
done

그 후 shift원본 콘텐츠는 $1목록에서 제거되었으며(그러나 우리는 이를 에 저장했습니다 $first_arg) 이제 원본 콘텐츠 $2는 에 있습니다 $1. 위치 매개변수는 다음과 같습니다.옮기다 1왼쪽 위치( shift 2이동 2의 경우...) 따라서 기본적으로 루프는 이전 두 번째 매개변수에서 마지막 매개변수까지 반복됩니다.

bash(and zshand ksh93, 하지만 그게 전부입니다)를 사용하는 또 다른 방법은 다음을 수행하는 것입니다.

for i in "${@:2}"
do something with "$i"
done

그러나 이는 표준 구문이 아니므로 sh에서 사용하면 안 됩니다 #! /bin/sh -.

zsh또는 에서는 yash다음을 수행할 수도 있습니다.

for i in "${@[3,-3]}"
do something with "$i"
done

세 번째 인수부터 세 번째이자 마지막 인수까지 반복합니다.

에서는 배열 이라고도 합니다 zsh. 따라서 배열의 시작이나 끝에서 요소를 팝하려면 다음을 수행할 수도 있습니다.$@$argv

argv[1,3]=() # remove the first 3 elements
argv[-3,-1]=()

( 다음 과 같이 쓸 shift수도 있음 )1=()zsh

에서는 bash내장을 사용하여 요소에만 할당할 수 있으므로 $@set에서 3개의 요소를 팝하려면 다음과 같이 하십시오.

set -- "${@:1:$#-3}"

그리고 세 번째부터 마지막 ​​세 번째까지 반복합니다.

for i in "${@:3:$#-5}"
do something with "$i"
done

POSIXly에서 마지막 3개 요소를 팝하려면 "$@"루프를 사용해야 합니다.

n=$(($# - 3))
for arg do
  [ "$n" -gt 0 ] && set -- "$@" "$arg"
  shift
  n=$((n - 1))
done

답변2

내 생각엔 당신이 shift내장된 것을 원하는 것 같아요. , to 등 $2으로 이름이 변경되었습니다 .$1$3$2

이와 같이:

shift
for i in "$@"; do
    echo $i
done

답변3

항상 원시인 접근 방식이 있습니다.

first=1
for i
do
        if [ "$first" ]
        then
                first=
                continue
        fi
        something with "$i"
done

이렇게 하면 그대로 유지되고 $@(나중에 사용하려는 경우) 단순히 각 매개변수를 반복하지만 첫 번째 매개변수는 처리하지 않습니다.

답변4

Bash에서는 명시적 인덱싱을 사용하여 이 루프를 작성할 수도 있습니다.

for ((i=2; i<=$#; ++i)); do
  process "${!i}"
done

이는 두 번째부터 마지막까지 모든 매개변수를 반복합니다. 마지막 매개변수를 제외하려면 다음을 수행하십시오.

for ((i=1; i<=$#-1; ++i)); do
  process "${!i}"
done

다른 모든 매개변수만 사용하려면 다음과 같이 작성하세요.

for ((i=1; i<=$#; i+=2)); do
  process "${!i}"
done

이 뒤에 숨겨진 이야기는산수버전for내장, 결합하다매개변수 개수$#그리고가변 간접${…}.

좋은 적용은 이것을 사용하여 주어진 옵션이 그 뒤에 오는 인수를 값으로 사용하는지 여부를 루프 내에서 결정할 수 있다는 것입니다. 그렇다면 증분 i(예: write : $((++i)))하여 다음 값을 사용하고 반복 중에 건너뜁니다.

관련 정보