zsh: 명령줄 인수를 두 문자열로 추출합니다.

zsh: 명령줄 인수를 두 문자열로 추출합니다.

내 스크립트는 원하는 수의 매개변수와 여러 옵션을 허용합니다.

모든 옵션과 첫 번째 매개변수를 문자열로 추출하고 나머지 매개변수를 두 번째 문자열로 추출해야 합니다. 즉:

./script.sh foo FILE1                     [s1="foo"  s2="FILE1]"
./script.sh foo FILE1 FILE2 FILE3         [s1="foo"  s2="FILE1 FILE2 FILE3]"

./script.sh -i -l foo FILE1               [s1="-i -l foo"  s2="FILE1]"
./script.sh -i -l foo FILE1 FILE2 FILE3   [s1="-i -l foo"  s2="FILE1 FILE2 FILE3]"

$@이 두 문자열로 분할하면 됩니다 . 매개변수를 다룰 필요가 없습니다 getopt. 즉, .

이를 수행하는 가장 쉬운 방법은 무엇입니까?

편집하다:문자열 대신 배열의 배열로 추출하면 트릭이 수행됩니다.

답변1

set -o extendedglob

first_set=("$@[1,(i)^-*]")
first=${(j[ ])first_set}

$first공백 문자로 시작하지 않고 첫 번째 인수까지 모든 인수를 연결하여 저장됩니다 .-

그런 다음 $second나머지를 얻을 수 있습니다.

second_set=("$@[$#first_set + 1, -1]")
second=${(j[ ])second_set}

아무튼 이건 $@아니니 참고하세요, 이는 0개 이상의 문자열 목록입니다.

예를 들어 명령줄을 사용하여 Bourne과 유사한 셸에서 스크립트를 호출하는 경우 다음과 같습니다.

script.sh -i   -l 'foo bar'   'File 1' File\ 2   "File 3"

그러면 스크립트가 실행됩니다.

execve("/path/to/script.sh", ["script.sh", "-i", "-l", "foo bar",
                              "File 1", "File 2", "File 3"], environ)

(스크립트가 로 시작한다고 가정 #! /bin/zsh -):

execve("/bin/zsh", ["/bin/zsh" /* or "script.sh" depending on the system*/,
                    "-", "/path/to/script.sh", "-i", "-l", "foo bar",
                    "File 1", "File 2", "File 3"], environ)

스크립트에서 이러한 모든 문자열은 $@다음 매개변수 argv[]에 포함됩니다 .execve()/path/to/script.sh

위에서는 목록을 두 부분으로 나눴습니다.세트( $first_set$second_set배열 변수), 그런 다음 이 세트의 매개변수를 두 개의 스칼라 변수( $first$second)로 연결합니다. 그러나 연결이 완료되면 더 이상 원래 매개변수 목록으로 돌아갈 수 없습니다. 예를 들어 $second이 경우에는 include 가 되며 File 1 File 2 File 3어떤 공백 문자가 인수를 구분하는 문자인지, 어느 문자가 인수의 일부인지 구별할 수 있는 방법이 없습니다.

관련 정보