zsh: 명령을 배열에 매핑

zsh: 명령을 배열에 매핑

배열이 있다고 가정 해 봅시다a=(foo 'bar baz')

각 배열 요소에 명령/함수를 적용하고 결과 문자열을 다른 배열에 저장하는 것보다 더 확실한 방법이 있습니까?

b=()
for e in $a; do
    b+=("$(my_cmd "$e")")
done

답변1

이에 대한 함수는 언제든지 선언할 수 있습니다.

map() {
  local arrayname="$1" cmd="$2" i
  shift 2
  eval "$arrayname=()"
  for i do
    eval "$arrayname+=(\"\$($cmd)\")"
  done
}

다음과 같이 사용됩니다.

$ a=(a '' bcd)
$ map b 'wc -c <<< "$i"' "$a[@]"
$ echo $b
2 1 4

답변2

명령이 배열 요소에 대해 수행하는 작업을 미리 알고 있는 경우 다음을 사용할 수 있습니다.매개변수 확장 플래그명령 출력을 어레이에 적용하는 방법에 대한 지침은 ( 참조 man zshexpn)zsh


배열에 a파일 이름이 포함되어 있고 각 파일 이름에는 한 줄의 텍스트만 포함되어 있다고 가정합니다.

$ a=(foo 'bar baz')
$ cat foo
A
$ cat 'bar baz'
B C

이제 논의를 위해 명령이 단순히 파일의 내용을 cat배열에 넣는다고 가정해 보겠습니다. b이 경우에는 반복하는 대신 간단히 다음과 같이 작성할 수 있습니다.

b=(${(f)"$(cat "${a[@]}")"})

여기서 (f)결과는 cat개행 문자로 구분된 단어로 분할됩니다.

결과는 예상대로입니다.

$ echo "${b[1]}"
A
$ echo "${b[2]}"
B C

실제 상황에 따라 플래그를 사용하여 다른 문자를 분할할 수 있습니다 ps:<character>:. (ps:\n:)위 예의 개행 문자 또는 NULL 문자 와 같은 일부 문자에는 각각 및 , (ps:\0:)약어가 있습니다 .(f)(0)

답변3

다음을 수행할 수 있습니다.

eval "b=(" '"$(cmd "$a['{1..$#a}']")"' ")"

그러나 이것은 덜 명확합니다.

답변4

참고 사항:

다음을 사용하여 단축할 수 있습니다.

for e ($a) b+=("$(my_cmd "$e")")

루프 $a는 null이 아닌 요소를 반복합니다. 모든 요소를 ​​반복하려면 "$a[@]".

관련 정보