다음과 같은 방식으로 실행되는 쉘 스크립트를 작성해야 합니다.
./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 zsh
and 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))
)하여 다음 값을 사용하고 반복 중에 건너뜁니다.