Frage 1

Frage 1

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 -cdie 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?

Ausgabe nach einem neuen Shell-Prompt

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 awkvermieden 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 \wauf ASCII-Buchstaben beschränkt ist. Fügen Sie ein hinzu, -Mopen=localeum je nach Gebietsschema alle Buchstaben in allen alphabetischen Schriftzeichen einzuschließen, wie in den grepoder 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 teeein Tool wiepee:

grep -o '^[[:alpha:]_]\+[[:blank:]]*([[:blank:]]*)' /etc/rc.d/init.d/functions | 
pee cat 'sleep 1; echo -e "\n`wc -l` matched."'

Wenn peedies nicht verfügbar ist, kann es mit einer separaten Shell durchgeführt werden bashund deren Eingabeaufforderungen mit unsetund 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:

  1. 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 Sie wc -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, (oder cat -n):

    printf "foo bar baz\nbuz biz\n" | grep -o 'b[^ ]*' | nl
    

    Ausgabe:

         1  bar
         2  baz
         3  buz
         4  biz
    
  2. 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
    

verwandte Informationen