コマンドを接続するときに、最後に実行されたコマンドから複数のコマンドの出力をどのように使用しますか?

コマンドを接続するときに、最後に実行されたコマンドから複数のコマンドの出力をどのように使用しますか?

次の2つのコマンドがあります。

これにより、リポジトリ名が提供されます。

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} あなたが考えるその意味ではありません...

関連情報