Wil*_*ard 3 io-redirection sort posix process-substitution join
由于必须对输入join进行排序,因此该命令的调用方式通常类似于:
join <(sort file1) <(sort file2)
Run Code Online (Sandbox Code Playgroud)
这是不可移植的,因为它使用了 POSIX 未指定的进程替换。
join-还可以通过指定为文件参数之一来使用标准输入。但是,这仅允许通过管道对其中一个文件进行排序:
sort file1 | join - <(sort file2)
Run Code Online (Sandbox Code Playgroud)
似乎应该有一种简单的方法来完成对两个文件的排序,然后仅使用 POSIX 指定的功能连接结果。也许使用重定向到第三个文件描述符,或者可能需要创建一个 FIFO。然而,我很难想象它。
如何join在未排序的文件上使用 POSIXly?
您可以使用两个命名管道来完成此操作(或者当然您可以使用一个命名管道和标准输入):
mkfifo a b
sort file1 > a &
sort file2 > b &
join a b
Run Code Online (Sandbox Code Playgroud)
进程替换本质上是通过设置这些 fifo(/dev/fd/在可用的情况下使用命名管道)来工作的。例如,在 bash 中:
$ echo join <(sort file1) <(sort file2)
join /dev/fd/63 /dev/fd/62
Run Code Online (Sandbox Code Playgroud)
请注意 bash 如何用文件名(在/dev/fd. (如果没有的话/dev/fd/,足够新的 zsh、bash 和 ksh93 版本将使用命名管道。)调用时,它们会保持打开状态join,因此当join打开它们时,它将从两个sorts 中读取。你可以看到它们通过了一些 lsof 技巧:
$ sh -c 'lsof -a -d 0-999 -p $$; exit' <(sort file1) <(sort file2)
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sh 1894 anthony 0u CHR 136,5 0t0 8 /dev/pts/5
sh 1894 anthony 1u CHR 136,5 0t0 8 /dev/pts/5
sh 1894 anthony 2u CHR 136,5 0t0 8 /dev/pts/5
sh 1894 anthony 62r FIFO 0,10 0t0 237085 pipe
sh 1894 anthony 63r FIFO 0,10 0t0 237083 pipe
Run Code Online (Sandbox Code Playgroud)
(这exit是为了防止一种常见的优化,即当只有一个命令要运行时 shell 不会分叉)。
| 归档时间: |
|
| 查看次数: |
723 次 |
| 最近记录: |