줄바꿈으로 서브쉘에서 zsh 배열 분할

줄바꿈으로 서브쉘에서 zsh 배열 분할

서브셸에서 zsh 배열을 인스턴스화하고 싶습니다.

myarray=($(somecommand)

내가 원하는 것을 받았는지 확인한다

for element in $myarray ; do echo "===" ; echo $element ; echo "---" ; done

기본적으로 요소를 구분하는 데 사용되는 공백(공백 및 개행)이 표시됩니다.

${(s:-:)"$(somecommand)"}또한 를 구분하여 사용할 수 있다는 것을 알았습니다 -. 이 경우 공백과 줄 바꿈이 요소를 분리하지 않습니다(예: 배열 요소에 줄 바꿈이 포함될 수 있음).

지금까지는 개행 문자에서만 분할할 수 없습니다. 즉, somecommand돌아오는 경우

Alice
Bob
Arthur C Clarke
Neo
Thomas Anderson

for위의 루프를 인쇄하고 싶습니다 .

===
Alice
---
===
Bob
---
===
Arthur C Clarke
---
===
Neo
---
===
Thomas Anderson
---

어떻게 이를 달성할 수 있나요? (설명서에서 이 내용을 찾을 수 있는 위치를 나타낼 수도 있습니다.)

답변1

기본 분할 연산자( $IFS따옴표가 없는 명령 대체에서 수행되는 Bourne과 같은 단어 분할 외에도)는 s매개변수 확장 플래그를 사용합니다.

array=(${(ps:\n:)"$(cmd)"})

cmd출력은 빈 요소(빈 줄)를 버리고 개행으로 분할됩니다.

p이러한 \x확장을 활성화하는 것입니다. 평소 와 같이 ps:\n:별칭이 더 짧습니다: ( f온라인 분할에프씨앗):

array=(${(f)"$(cmd)"})

빈 줄을 유지하려면 다음을 수행하십시오.

array=("${(f@)$(cmd)"})

이제 대부분의 다른 쉘과 마찬가지로 명령 대체 표시줄이모두후행 개행 문자이므로 모든 후행 공백 행입니다. 이를 보존하려면 다음을 수행할 수 있습니다.

array=("${(f@)$(cmd; echo .)}")
array[-1]=()  # remove that last line added by echo .

분사 로 $IFS:

IFS=$'\n'
array=($(cmd)) # removes empty lines. Note that contrary to other
               # Bourne-like shells, zsh doesn't do globbing there
               # so you don't need the "set -o noglob"

IFS=$'\n\n' # like in ksh93, doubling an IFS-whitespace character
            # removes its special treatment as a whitespace character
array=($(cmd)) # preserves empty lines except the trailing ones

IFS=$'\n\n'
array=($(cmd; echo .)); array[-1]=() # preserves all empty lines.

전역 수정을 방지하려면 $IFS익명 함수에서 위의 작업을 수행할 수 있습니다.

(){
  local IFS=$'\n\n'
  array=($(cmd; echo .)); array[-1]=()
}

또한 $array확장은 빈 요소를 건너뜁니다. 따라서 루프를 원할 경우모두빈 요소를 포함하는 요소의 경우 다음을 수행해야 합니다.

for i ("$array[@]") ...

또는

for i ("${(@)array}") ...

아니요

for i ($array) ...
for i in $array

관련 정보