So verketten Sie zwei Befehle in der Shell

7

Früher hatte ich diesen Befehl, um zu zählen, wie oft ich mit der Maus geklickt habe xev | grep "ButtonPress".

Mein Kollege ändert den Befehl so, dass er zurückgibt:

ButtonPress 0
ButtonPress 1
ButtonPress 2
ButtonPress 3

und so weiter ... Leider ist er nicht mehr erreichbar, so dass ich ihn nicht mehr erreichen kann.

Ich erinnere mich an die Beteiligung i++und so etwas, wie man den Befehl reproduziert.

Jackie Nelson
quelle
Meinen Sie xev | grep -c "ButtonPress", die Anzahl der Klicks beim Beenden anzeigen?
Dessert
Es zeigt ButtonPress+ Nummer jedes Mal, wenn ich auf das White-Box-Popup-Fenster klicke, sorry, ich bin ein Neuling ...
Jackie Nelson
Dessert, Ihr Befehl hat funktioniert, aber er gibt die Nummer erst zurück, wenn ich gehe xev. Wie kann man dafür sorgen, dass der Live-Wert zurückgegeben wird?
Jackie Nelson

Antworten:

11

Die Tatsache, dass es gibt, i++deutet darauf hin, dass entweder bashoder eine kshShell verwendet wurde, möglicherweise awkoder perlauch. In beiden Fällen können wir die Prozessersetzung verwenden <(...) , um die Ausgabe der xevZählschleife zuzuführen (obwohl eine einfache Pipeline xev | while...problemlos funktionieren könnte).

Textverarbeitungswerkzeuge :

Portabel und für weniger Tastenanschläge können wir verwenden awk:

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

perl Ausführung:

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

Muscheln :

Folgendes funktioniert in 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

Falls Sie nicht möchten, dass viele Zeilen spammig ausgegeben werden, können Sie printfSteuercode senden, um die vorherige Zeile zu löschen und nur die laufende Anzahl auszugeben (dh, Sie sehen nur eine Änderung des ganzzahligen Werts in der Zeile):

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

Portabel in der 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

Grundausstattung :

Auf einfache, schnelle und schmutzige Weise können wir dies hacken, cat -nindem die Zeilenanzahl links statt rechts gedruckt wird:

$ 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,
Sergiy Kolodyazhnyy
quelle
Ich habe Ihren ersten Befehl ausprobiert, der awk enthält. Er funktioniert, aber es gibt eine gewisse Verzögerung, wenn die Ausgabe zurückkehrt
Jackie Nelson,
Ihr zweiter und dritter Befehl funktionieren jedoch perfekt, vielen Dank Sergiy
Jackie Nelson
@JackieNelson Eine gewisse Verzögerung könnte auf eine Pufferung hindeuten, die möglicherweise mit einer anderen verwendeten awkVersion zusammenhängt. Die letzten Ubuntu-Anwendungen gawkund vor 16.04 waren standardmäßig mawkIIRC.
Trotzdem
Können Sie dafür sorgen, dass die Nummer bei der perlVersion eins beginnt ? Nicht null
Jackie Nelson
@JackieNelson Yep, hat das bereits geändert
Sergiy Kolodyazhnyy