내용이 포함된 파일이 있습니다 f1
.
james john joe
marie james
joe
don marie
grep
쉘 스크립트에서 다음을 사용하여 s1.sh
각 줄의 명령줄 매개변수 발생을 출력 하고 싶습니다 .
#!/bin/bash
for ((i = $# ; i > 0 ; i-- ))
do
grep -c $i f1
done
다음과 같이 실행한다고 가정해 보겠습니다.
s1.sh james joe
스크립트가 변수를 i
위치 매개변수로 해석하도록 하려면 어떻게 해야 합니까?
답변1
스크립트의 인수를 한 번에 하나씩 사용하려는 경우 grep
산술 루프를 수행할 필요가 없습니다 for
.
#!/bin/sh
for pattern do
grep -c -e "$pattern" f1
done
이 for
루프는 스크립트의 매개변수인 위치 매개변수를 반복합니다. 각 반복에서 이 값은 $pattern
다음 명령줄 인수가 됩니다.
또한 대시로 시작하는 패턴이 options 로 잘못 해석되지 않도록 하기 위해 -e
위의 방법을 사용합니다 . 또한 단어 분리 및 파일 이름 글로빙을 방지하기 위해 패턴을 참조했습니다.grep
grep
패턴이 실제로 정규 표현식이 아닌 문자열인 경우 grep
with 사용을 고려하세요 -F
.
위치 인수 목록을 사용할 수 "$@"
있으며 위의 루프는 이를 암시적으로 사용합니다. 반복하려면 "$@"
다음을 사용하십시오.
for pattern in "$@"; do
...
done
인용은 필수적입니다. 그렇지 않으면 스크립트 인수에 대해 토큰화 및 파일 이름 일치를 수행하게 됩니다.
이 답변에는 쉘 코드가 필요하지 않으므로 -line을 사용하고 bash
있습니다 ./bin/sh
#!
답변2
스크립트가 변수를
i
위치 매개변수로 해석하도록 하려면 어떻게 해야 합니까?
아마도 Bash에서 변수로 인덱스된 위치 인수를 얻는 가장 간단한 방법은 배열 슬라이스 표기법을 위치 인수에 $@
.extended 에 적용하는 것입니다."${@:n:k}"
N도착하다n+k-1에서 까지 "${array[@]:n:k}"
배열 요소 로 확장하는 것과 같습니다."${array[n]}"
"${array[n+k-1]}"
N그리고케이평가를 위해 쉘 산술을 사용하므로 예를 들어 position 에 인수가 하나만 "${@:a+b-1:1}"
주어 지면 이를 수행할 수 있습니다 ."${@:i:1}"
i
또는 간접 확장 ${!var}
도 위치 인수를 처리하므로 예를 들어 with 가 i=2
제공 "${!i}"
됩니다 "$2"
. 음, 이것도 위의 것보다 짧습니다. 반면에 namerefs는아니요위치 매개변수를 사용하면 declare -n ref=2
오류가 발생합니다...
예를 들어 참조하십시오.Bash는 포인터 사용을 지원합니까?
또 다른 접근 방식은 위치 인수 목록을 명명된 배열에 복사한 다음 일반적인 방법으로 색인을 생성하는 것입니다. args=("$@")
복사해서 사용하세요 "${args[i]}"
. 여기서도 인덱스는 산술 확장입니다.
물론, 위치 매개변수에 액세스하려는 경우증가평소와 같이 순서에는 실제로 표시된 역순이 필요하지 않으며 Kusalanda의 답변에 표시된 것처럼 for x in "$@"; do ...
or 을 사용하면 됩니다.for x do ...
그러나 동일한 루프 구성을 사용하여 위치 인수 목록을 먼저 뒤집을 수도 있습니다. 예를 들어 dd cc bb aa
, 이름 지정자, 역참조 또는 배열이 없는 일반 sh에서도 다음과 같이 인쇄됩니다.
set -- aa bb cc dd
first=1
for x in "$@"; do
# on first iteration, clear the list
[ "$first" = 1 ] && set --
first=
set -- "$x" "$@"
done
echo "$@"