我有一个小的 AWK 脚本,它总结了另一个程序的输出,我试图在命令本身之前打印该摘要,但我找不到一个好的方法来做到这一点。我天真的第一个解决方案是运行命令两次,一次获取摘要信息,一次打印带有前置摘要的完整输出。现在我习惯tee
只读取一次程序输出,然后使用head
和tail
来移动它,这比以前的版本快了大约 3 倍。
当前版本看起来像
program | awk ... | tee >(head -n -3) >(tail -n -3) > /dev/null
它确实提供了所需的输出,但不如我确信的那样优雅(和快速)。至少我认为有一种方法不必重定向到 /dev/null,但我无法弄清楚实现这种情况的安排。
我已经使用 看到了类似问题的一些答案ed
,我也想这样做,但是当我尝试将命令通过管道传输到其中时,它ed
不起作用。具体来说,我认为
echo -e "$-2,$m0\n,p\nQ" | ed <(program | awk ...)
应该可以工作,因为运行这些命令本身确实ed
可以,但我已将问题范围缩小到“$-2”地址,该地址在管道输入时似乎不起作用,ed
但在直接运行它时却起作用。我已经在 GNU 版本 1.9 和 1.16 上测试了该部分。在这两种情况下使用该-v
选项只会给我带来“无效的命令后缀”错误。甚至跑步
echo "$-2,$p" | ed -v filename
产生这个错误,所以这不是进程替换的问题。我显然怀疑我在使用 ed 不到一个小时后发现了它的错误,所以我想我应该在这里问一下我做错了什么。我也对任何不涉及 ed 的解决方案持开放态度,我只是认为这似乎是一个有前途的方法。
如果有帮助的话,“程序”就是qstat
,AWK 只是计算用户正在运行、排队和退出的作业数量,并在最后打印总数。可能有一些 qstat 选项可以做我想要内置的事情,但我还没有在手册中找到它们,所以这也将是一个有用的答案!我真的很想了解我的ed
命令出了什么问题。
答案1
你实际上已经偶然发现了壳,不在编辑上。这
echo -e "$-2,$m0\n,p\nQ"
意味着$-
并$m0
经历参数扩展,因为它们用双引号引起来。跑过去echo "$-"
亲眼echo "$m0"
看看。它们应该用单引号引起来,这样 shell 就不会展开它们。
既然我们正在修复它,那么我们也偏爱printf
于echo
。后者在各个实现中具有不一致的行为,而前者是健全的。这应该做:
printf '%s\n' '$-2,$m0' ',p' 'Q' | ed -s <(program | awk ...)
-s
选项已添加到 ed,以便“抑制诊断、字节计数和 '!'迅速的”。这纯粹是装饰性的。
示例执行(无用地使用 cat 来模拟进程替换):
$ cat input
ATOM 126 CD GLN A 449 -2.853 11.592 119.709 1.00 17.95 C
ATOM 127 OE1 GLN A 449 -4.056 11.297 119.695 1.00 20.83 O
ATOM 128 NE2 GLN A 449 -1.948 10.876 120.359 1.00 14.98 N
HETATM 129 N MSE A 450 -4.523 16.830 119.280 1.00 14.88 N
HETATM 130 CA MSE A 450 -5.537 17.804 118.911 1.00 15.65 C
$ printf '%s\n' '$-2,$m0' ',p' 'Q' | ed -s <(cat input)
ATOM 128 NE2 GLN A 449 -1.948 10.876 120.359 1.00 14.98 N
HETATM 129 N MSE A 450 -4.523 16.830 119.280 1.00 14.88 N
HETATM 130 CA MSE A 450 -5.537 17.804 118.911 1.00 15.65 C
ATOM 126 CD GLN A 449 -2.853 11.592 119.709 1.00 17.95 C
ATOM 127 OE1 GLN A 449 -4.056 11.297 119.695 1.00 20.83 O