コマンドに「参加」できますか?

コマンドに「参加」できますか?

joinとても便利だと思います。これにより、キーフィールドでfile1とfile2を組み合わせることができます。

コマンドの結果に応じてこれを動的に実行することは可能ですか?たとえば、次のようになります。

join -1 1 -2 1 file1 'curl http://example.com?code=$1&fmt=csv'

おそらくxargsまたは名前付きパイプを使用できますか?

理想的には、file1の各レコード/行に対して「検索」を実行します。

答え1

はい、シェルがプロセス置換をサポートしている場合(bashそしてksh93実際にはそうです)、次のことができます。

$ join file1 <( yourcommand )

これにより、コマンドが実行され、join標準出力に関連付けられたファイル記述子が使用されますfile1/dev/fdyourcommandcurl

joinすべての入力は整列する必要があります。ソートされた入力ストリームは一度だけ解析できる必要があります。特に入力をソートする必要がありますsort -b(先行スペースは無視されます)。

そうでない場合は、次のことができます。

$ join <( sort -b file1 ) <( yourcommand | sort -b )

答え2

コマンドから入力ファイルを1つだけインポートする必要がある場合は、単純なパイプで十分です。-標準入力を表すファイル名として使用されます。

curl 'http://example.com?code=$1&fmt=csv' | join -1 1 -2 1 file1 -

両方のファイルをパイプからインポートする必要がある場合は、デフォルトのシェル機能以上の機能が必要です。 Ksh、bash、zshではプロセスの交換、プログラムがファイル名を期待する場所であれば、どこでもコマンドの出力をパイプできます。

curl 'http://example.com?code=$1&fmt=csv' | sort |
join -1 1 -2 1 <(sort file1) -

または均等に対称

join -1 1 -2 1 <(<file1 | sort) \
               <(curl 'http://example.com?code=$1&fmt=csv' | sort)

通常のshにはプロセスの交換はありません。複数のパイプから入力を受け取るためのコマンドが必要な場合、移植可能なソリューションは名前付きパイプを使用することです。

tmp="$(mktemp -d)"
mkfifo "$tmp/p"
sort <file1 >"$tmp/p" &
curl 'http://example.com?code=$1&fmt=csv' | sort | join -1 1 -2 1 "$tmp/p" -
rm "$tmp/p"
rmdir "$tmp"

関連情報