
Frage 1
ich kann nutzen
grep -o '^[[:alpha:]_]\+[[:blank:]]*([[:blank:]]*)' /etc/rc.d/init.d/functions
um eine Ausgabe wie unten zu erhalten:
systemctl_redirect ()
checkpid()
__kill_pids_term_kill_checkpids()
__kill_pids_term_kill()
__pids_var_run()
__pids_pidof()
daemon()
killproc()
pidfileofproc()
pidofproc()
status()
echo_success()
echo_failure()
echo_passed()
echo_warning()
update_boot_stage()
success()
failure()
passed()
warning()
action()
strstr()
is_ignored_file()
is_true()
is_false()
apply_sysctl()
Und ich möchte auch wissen, wie viele Vorkommen abgeglichen wurden, also benutze ich -c
die Option, dieses Mal bekomme ich nur 26
, kann ich übereinstimmende Inhalte und Zählungen kombinieren mitgrep
eingebautOptionen? Wenn nicht, wie?
Frage 2
Ich habe auf Github eine Lösung zur Beantwortung von Frage 1 gefunden:
grep -o '^[[:alpha:]_]\+[[:blank:]]*([[:blank:]]*)' /etc/rc.d/init.d/functions \
| tee >(echo -e "\n`wc -l` matched.")
Aber die Ausgabe ist oft seltsam, die nach einem neuen ausgegeben wirdShell-Eingabeaufforderung!Warum?
Antwort1
Sie können jederzeit Folgendes tun:
grep -o ... | awk '{print};END{if (NR) print "\n" NR " matched."}'
Oder machen Sie das Ganze in (wodurch auch die und GNUismen awk
vermieden würden ):-o
\+
awk 'match($0, /^[[:alpha:]_]+[[:blank:]]*\([[:blank:]]*\)/) {
print substr($0, RSTART, RLENGTH)
n++
}
END{if (n) print "\n" n " matched.")'
oder perl
:
perl -lne 'for (/^\w+\h*\(\h*\)/g) {print; $n++}
END {print "\n$n matched." if $n}'
(Beachten Sie, dass in diesem Fall \w
auf ASCII-Buchstaben beschränkt ist. Fügen Sie ein hinzu, -Mopen=locale
um je nach Gebietsschema alle Buchstaben in allen alphabetischen Schriftzeichen einzuschließen, wie in den grep
oder awk
(einigen awk
) Ansätzen.)
Zu Ihrer Frage 2: Das liegt daran, dass bash
(im Gegensatz zu zsh
) nicht auf Befehle wartet, die bei der Prozessersetzung gestartet wurden, was diese Art von Problem verursacht. SieheDie Ausgabe der Prozesssubstitution liegt nicht in der richtigen Reihenfolgefür mehr Details.
Antwort2
Verwenden Sie stattdessen tee
ein Tool wiepee
:
grep -o '^[[:alpha:]_]\+[[:blank:]]*([[:blank:]]*)' /etc/rc.d/init.d/functions |
pee cat 'sleep 1; echo -e "\n`wc -l` matched."'
Wenn pee
dies nicht verfügbar ist, kann es mit einer separaten Shell durchgeführt werden bash
und deren Eingabeaufforderungen mit unset
und stummgeschaltet werden shopt
:
bash -c \
"unset PS0 PS1 PS2 PS3
shopt -u promptvars
grep -o '^[[:alpha:]_]\+[[:blank:]]*([[:blank:]]*)' \
/etc/rc.d/init.d/functions |
tee >( sleep 1s; printf '\n%s matched.' `wc -l`; )
sleep 2s"
Allgemeine Antworten:
Dies ist mit einer einzelnen Instanz von nicht möglich
grep
.Um eine vollständige Zählung zu erhalten, wenn es mehr als eine Übereinstimmung pro Zeile mit gibt
grep -o
, verwenden Siewc -l
:printf "foo bar baz\nbuz biz\n" | grep -o 'b[^ ]*' | wc -l
Ausgabe:
4
Wenn eine vorangestellte Anzahl benötigt wird, verwenden Sie
nl
, (odercat -n
):printf "foo bar baz\nbuz biz\n" | grep -o 'b[^ ]*' | nl
Ausgabe:
1 bar 2 baz 3 buz 4 biz
Mit parallelen Prozessendh
tee >(echo -e "\n`wc -l` matched.")
Es gibt keine Garantie, welcher Vorgang zuerst abgeschlossen wird. Manchmal kann eine kleine Verzögerung einkalkuliert werden, um die Bestellung zu gewährleisten.
Parallel drucken »foo" Zuerst, dann "uff" nach einer Verzögerung von 1 Sekunde:
echo foo | tee >(sleep 1s; rev)
Parallel drucken »uff" Zuerst, dann "foo" nach einer Verzögerung von 1 Sekunde:
echo foo | tee >(rev) >(sleep 1s;cat) > /dev/null