shell 中如何连接两个命令

shell 中如何连接两个命令

我曾经用这个命令来计算我用鼠标点击的次数,该命令是xev | grep "ButtonPress"

我的同事修改了命令以便它返回:

ButtonPress 0
ButtonPress 1
ButtonPress 2
ButtonPress 3

等等...不幸的是,他已经无法联络了,所以我再也无法联系到他了。

我记得涉及i++类似的东西,如何重现命令?

答案1

有这个事实表明,可能也i++bashksh正在使用的 shell 。无论哪种情况,我们都可以使用awkperl流程替代 <(...)将输出提供给xev计数循环(尽管简单的管道xev | while...就可以正常工作)。

文本处理工具

我们可以使用以下便携且更少的按键awk

$ xev | awk '/ButtonPress/{print "ButtonPress",i++}'
ButtonPress 0
ButtonPress 1
ButtonPress 2
ButtonPress 3

perl版本:

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

贝壳

以下是有效的方法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

如果您不想输出多行垃圾信息,我们可以使用printf发送控制代码来清除前一行并仅输出运行计数(也就是说,您只会看到该行上的整数值变化):

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

在 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

基本工具

为了简单、快速且粗略地解决这个问题,我们可以通过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,

相关内容