如何在shell中连接两个命令

Jac*_*son 7 command-line bash scripts dash-shell

我曾经用这个命令来计算我用鼠标点击了多少次,命令是xev | grep "ButtonPress".

我的同事修改了命令,使其返回:

ButtonPress 0
ButtonPress 1
ButtonPress 2
ButtonPress 3
Run Code Online (Sandbox Code Playgroud)

等等......不幸的是,他不再能联系上,所以我无法再联系到他。

我记得参与i++和类似的事情,如何重现命令?

Ser*_*nyy 11

事实i++表明,可能或同时使用了 shellbashkshshell 。在任何一种情况下,我们都可以使用进程替换将输出提供给计数循环(尽管简单的管道可以正常工作)。awkperl <(...)xevxev | while...

文本处理工具

我们可以使用便携式和更少的击键awk

$ xev | awk '/ButtonPress/{print "ButtonPress",i++}'
ButtonPress 0
ButtonPress 1
ButtonPress 2
ButtonPress 3
Run Code Online (Sandbox Code Playgroud)

perl 版本:

$ xev | perl -ne '/ButtonPress/ && printf("ButtonPress:%d\n",++$i)'
ButtonPress:1
ButtonPress:2
ButtonPress:3
Run Code Online (Sandbox Code Playgroud)

贝壳

以下是适用的内容bash

$ i=0; while IFS= read -r line; do [[ $line =~ ButtonPress ]] && { ((i++)); printf 'ButtonPress: %d\n' "$i";} ;done < <(xev)
ButtonPress: 1
ButtonPress: 2
ButtonPress: 3
Run Code Online (Sandbox Code Playgroud)

如果您不希望多行的垃圾邮件输出,我们可以使用printf发送控制代码来清除前一行并仅输出运行计数(即您只会在该行看到整数值的变化):

$ i=0; while IFS= read -r line; do [[ $line =~ ButtonPress ]] && { ((i++)); printf "\r%b" "\033[2K"; printf 'ButtonPress: %d' "$i";} ;done < <(xev)
Run Code Online (Sandbox Code Playgroud)

在 POSIX shell 中可移植:

$ xev | ( i=0; while IFS= read -r l; do case "$l" in  *ButtonPress*) i=$((i+1)) && printf 'ButtonPress:%d\n' "$i";;  esac ;done)
ButtonPress:1
ButtonPress:2
ButtonPress:3
Run Code Online (Sandbox Code Playgroud)

基本实用程序

对于简单、快速和肮脏的方式,我们可以通过cat -n在左侧而不是右侧打印行数来破解它:

$ xev | grep --line-buffered 'ButtonPress' | cat -n
     1  ButtonPress event, serial 34, synthetic NO, window 0x4a00001,
     2  ButtonPress event, serial 34, synthetic NO, window 0x4a00001,
     3  ButtonPress event, serial 34, synthetic NO, window 0x4a00001,
Run Code Online (Sandbox Code Playgroud)