web-dev-qa-db-ja.com

シェルで2つのコマンドを連結する方法

以前は、このコマンドを使用して、マウスでクリックした回数をカウントしていました。このコマンドはxev | grep "ButtonPress"です。

私の同僚は、コマンドが戻るようにコマンドを変更します。

ButtonPress 0
ButtonPress 1
ButtonPress 2
ButtonPress 3

など...残念ながら彼は連絡が取れなくなったので、もう連絡が取れません。

i++の関与などを思い出しました。コマンドを再現するにはどうすればよいですか。

7
Jackie Nelson

_i++_があるという事実は、bashまたはkshシェルのいずれかが使用されていたことを示唆しており、潜在的にawkまたはPerlも使用されています。どちらの場合でも、 プロセス置換<(...)を使用して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シェルで移植可能:

_$ 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,
_
11