我觉得join
非常有用。它允许您在关键字段上将 file1 与 file2 连接起来。
是否可以根据命令的结果动态地执行此操作,例如:
join -1 1 -2 1 file1 'curl http://example.com?code=$1&fmt=csv'
也许使用 xargs 或命名管道?
理想情况下,它会对 file1 中的每条记录/行执行一次“查找”
答案1
是的,如果您的 shell 支持进程替换(bash
并且ksh93
确实如此),您可以这样做:
$ join file1 <( yourcommand )
这将运行join
命令并使用连接到标准输出的file1
文件描述符(这将是您的东西)。/dev/fd
yourcommand
curl
请注意,join
期望所有输入都进行排序。它要求排序的输入流只能解析一次。特别是,输入需要进行排序sort -b
(忽略前导空格)。
如果不是这种情况,你可以这样做:
$ join <( sort -b file1 ) <( yourcommand | sort -b )
答案2
如果只有一个输入文件需要来自命令,则一个简单的管道就足够了。用作-
文件名表示标准输入。
curl 'http://example.com?code=$1&fmt=csv' | join -1 1 -2 1 file1 -
如果两个文件都需要来自管道,那么您需要的不仅仅是基本 shell 功能。 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"