명령을 연결할 때 마지막으로 실행된 명령에서 여러 명령의 출력을 어떻게 사용합니까?

명령을 연결할 때 마지막으로 실행된 명령에서 여러 명령의 출력을 어떻게 사용합니까?

다음과 같은 두 가지 명령이 있습니다.

그러면 저장소 이름이 제공됩니다.

az acr repository list -n registry -o tsv 

출력은 다음과 같습니다.

name1
name2
...

이는 저장소의 요약 코드를 제공합니다.

az acr manifest list-metadata -r ${REGISTRY} --name ${REPO} --query "[?tags[0]==null].digest" -o tsv

출력은 다음과 같습니다.

digest1
digest2
...

저장소 이름과 요약 코드를 출력하고 싶습니다.

시험을 마친:

az acr repository list -n registry -o tsv \ 
| xargs -I% az acr manifest list-metadata -r ${REGISTRY} --n % --query "[?tags[0]==null].digest" -o tsv \
| xargs -I% echo "%: %" 

실제 출력:

digest_code: digest_code

예상 출력:

repo_name: digestcode

답변1

다음과 같은 것이 필요합니다.

export REPO
az acr repository list -n registry -o tsv |
  while IFS= read -r REPO; do
    az acr manifest list-metadata -r "$REGISTRY" --n "$REPO" --query '[?tags[0]==null].digest' -o tsv |
      awk '{print ENVIRON["REPO"]": "$0}'
  done

호출은 awk각 인벤토리 명령의 출력 앞에 해당 저장소 이름을 붙입니다.

또는 각 리포지토리/다이제스트 쌍에서 추가 명령을 실행해야 하는 경우:

az acr repository list -n registry -o tsv |
  while IFS= read -r repo; do
    az acr manifest list-metadata -r "$REGISTRY" --n "$repo" --query '[?tags[0]==null].digest' -o tsv |
      while IFS= read -r digest; do
        other-cmd --repo "$repo" --digest "$digest"
      done
  done

를 사용하면 zsh다음 작업도 수행할 수 있습니다.

for repo ( ${(f)"$(az acr repository list -n registry -o tsv)"} ) {
  digests=( ${(f)"$(az acr manifest list-metadata -r $REGISTRY --n $repo --query '[?tags[0]==null].digest' -o tsv)"})
  print -rC1 -- $repo': '$^digests
}
for repo ( ${(f)"$(az acr repository list -n registry -o tsv)"} )
  for digest ( ${(f)"$(az acr manifest list-metadata -r $REGISTRY --n $repo --query '[?tags[0]==null].digest' -o tsv)"})
    other-cmd --repo $repo --digest $digest

에서는 Makefile다음과 같습니다.

target:
    az acr repository list -n registry -o tsv | \
      while IFS= read -r repo; do \
        az acr manifest list-metadata -r "$$REGISTRY" --n "$$repo" --query '[?tags[0]==null].digest' -o tsv | \
          while IFS= read -r digest; do \
            other-cmd --repo "$$repo" --digest "$$digest"; \
          done; \
      done

Makefile에 여러 줄이 있지만 줄을 연결하고 뒤따르는 s를 제거하고 \결과를 전달하기 전에$$ s를 s로 변경하므로 인라인 셸 스크립트 Order에서 이를 구분하려면 몇 개의 s를 추가해야 합니다.$sh -c;

더 명확하게 만들기 위해 코드를 스크립트에 넣을 수도 있습니다.

답변2

추측하다,시도한 솔루션과 원하는 기타 답변을 리버스 엔지니어링하여n₁ + n2 + …다음과 같은 출력 라인

blue: sky
blue: berry
blue: jay
red: stop sign
red: cardinal
red: tomato
red: fire
green: grass
green: beans

Stefan Chazeras의 답변괜찮습니다. 특히 저장소 이름에 어떤 문자가 있을지 모르는 경우에는 더욱 그렇습니다. 그러나 아주 오래된 버전의 Awk에서는 작동하지 않습니다.

이 매우 유사한 답변은 Awk 대신 sed를 사용합니다. sed는 리소스 집약도가 낮고 더 빠르게 실행될 수 있습니다.

az acr repository list -n registry -o tsv |
  while IFS= read -r REPO; do
    az acr manifest list-metadata -r "$REGISTRY" --name "$REPO" \
                    --query "[?tags[0]==null].digest" -o tsv |
        sed "s/^/$REPO: /"
  done

( 필수는 아님) 저장소 이름에 또는 가  export포함될 수 있다는 점을 제외하면 Stéphane의 답변과 동일해야 합니다 . 일반적으로 사용되지만 임의의 구분 기호 입니다  . 저장소 이름에 다음이 포함되어 있지 않다고 확신하는 경우  명령을 다음으로 변경하여 더 안전하게 만들 수 있습니다./&/&|sed

        sed "s|^|$REPO: |"

저장소 이름에  &.

저장소 이름이나 요약 코드에 .

저장소 이름이나 코드 조각에 공백이 포함되어 있지 않으면 출력을 column -t.


그런데 좀 보세요${variable_name} 당신이 생각하는 그런 의미는 아니죠....

관련 정보