it-swarm.com.de

Holen Sie sich den Ausgabe- und Rückgabewert von grep in einer einzelnen Operation in bash

Ich schreibe ein Bash-Skript. Ich führe einen bestimmten Befehl aus und grep.

pfiles $1 2> /dev/null | grep name # $1 Process Id

Die Antwort wird ungefähr so ​​sein:

sockname: AF_INET6 ::ffff:10.10.50.28  port: 22
peername: AF_INET6 ::ffff:10.16.6.150  port: 12295

Die Antwort kann keine Zeilen, 1 Zeile oder 2 Zeilen sein.
Falls grep keine Zeilen zurückgibt (grep-Rückkehrcode 1), brich ich das Skript ab; Wenn ich 1 Zeile erhalte, rufe ich A() oder B() wenn mehr als 1 Zeile. Der Rückkehrcode von grep ist 0, wenn die Ausgabe 1-2 ist Linien.

grep hat den Rückgabewert (0 oder 1) und die Ausgabe.
Wie kann ich beide fangen? Wenn ich so etwas mache wie:

OUTPUT=$(pfiles $1 2> /dev/null | grep peername)

Dann hat die Variable OUTPUT die Ausgabe (Zeichenfolge); Ich möchte auch den booleschen Wert der grep-Ausführung.

7
ilansch

Sie können verwenden

output=$(grep -c 'name' inputfile)

Die Variable output enthält dann die Nummer 0, 1, oder 2. Dann können Sie eine if - Anweisung verwenden, um verschiedene Dinge auszuführen.

11
pfnuesel

Das ist ziemlich einfach:

OUTPUT=$(pfiles "$1" 2> /dev/null | grep peername)
grep_return_code=$?

Wenn einer Variablen eine $(…) - Befehlssubstitution zugewiesen wird, erhält $? Den Rückkehrcode vom letzten Befehl in $(…). Und natürlich müssen Sie nicht explizit auf $? Verweisen. Sie können Dinge wie tun

wenn OUTPUT = $ (pfiles "$ 1" 2>/dev/null | grep peername) 
 dann 
 # der Rest des Skripts
 ︙ 
 Fi

oder

wenn ! OUTPUT = $ (pfiles "$ 1" 2>/dev/null | grep peername) 
 Dann 
 Beenden Sie 
 Fi 
 # der Rest des Skripts

Dieser Ansatz ist in Situationen nützlich, in denen Ausgabe des Befehls und sein Rückkehrcode (a.k.a. Exit-Status) nicht korreliert sind. Aber für grep sind sie stark korreliert: Wenn es Ausgabe produzierte, war es erfolgreich. Wenn keine Ausgabe erstellt wurde, ist ein Fehler aufgetreten. Warum also nicht einfach die Ausgabe testen?

OUTPUT = $ (pfiles "$ 1" 2>/dev/null | grep peername) 
 Wenn ["$ OUTPUT"] 
 Dann 
 # der Rest des Skripts
 ︙ 
 Fi

oder

OUTPUT = $ (pfiles "$ 1" 2>/dev/null | grep peername) 
 If [-z "$ OUTPUT"] 
 Dann 
 Beenden Sie 
 Fi 
 # der Rest des Skripts

P.S. Sie sollten immer Ihre Shell-Variablenreferenzen (z. B. "$1") Zitieren, es sei denn, Sie haben einen guten Grund, dies nicht zu tun, und Sie sind sicher, dass Sie wissen, was Sie tun.

1
Scott

Wenn Sie das Ergebnis von grep benötigen, können Sie das Flag -c Nicht wie in der anderen Antwort beschrieben verwenden. Sie können jedoch zweimal ausführen, einmal mit dem Flag -c, Um die Anzahl der Übereinstimmungen zu ermitteln, und einmal ohne das Flag -c, Um die Übereinstimmungen anzuzeigen. Dies kann jedoch abhängig von der Größe Ihrer Eingabedatei sehr ineffizient sein.

Sie können so etwas tun:

Inhalt von Eingabe:

The first line is foo
I have a drink at the bar
The third line is foo again

Inhalt von Skript:

#!/usr/bin/env bash

countMatches(){
    echo Searching for "${1}"
    result=$(grep "${1}" input)
    if [ $? -eq 1 ]; then
        echo No match found
        echo
        exit 1
    fi

    if [ $(echo "${result}" | wc -l) -eq 1 ]; then
        echo 1 match found:
        echo "${result}"
        echo
    else
        echo 2 matches found:
        echo "${result}"
        echo
    fi
}

countMatches foo
countMatches bar
countMatches baz

Und hier ist die Ausgabe, wenn Sie das Skript aufrufen:

Searching for foo
2 matches found:
The first line is foo
The third line is foo again

Searching for bar
1 match found:
I have a drink at the bar

Searching for baz
No match found
1
pfnuesel

Versuchen Sie diesen Code, ich glaube, er macht, was Sie wollen.

  1. Ich habe die Ausgabe grep in die Variable OUTPUT eingefügt
  2. Ich denke, Sie brauchen den Exit-Status grep nicht als booleschen Wert. Es ist 0 oder 1 und passt nicht zu Ihrer Aufgabe. Sie benötigen die Anzahl der Zeilen - 0, 1, 2 usw. Zählen Sie daher die Zeilen in der OUTPUT-Variablen und setzen Sie diese Zahl in die zweite Variable - line_count. Wir werden zwei Variablen im Ergebnis haben. Erstens mit Grep-Ausgabe, zweitens mit Zeilenanzahl.
  3. Dann überprüfe line_count in der Anweisung case und führen Sie die erforderlichen Aktionen aus.

Verwendung :./switching_by_grep_result.sh your_file.txt

#!/bin/bash

# your code
OUTPUT=$(pfiles $1 2> /dev/null | grep name) # $1 Process Id

# count lines in the OUTPUT variable by using 'grep -c'
line_count=$(echo -n "$OUTPUT" | grep -c '^')

# checks lines count in here and invokes needed script or exit.
# if 0 lines - exit
# if 1 lines - invoke A
# if any other number of lines - invoke B
case $line_count in  
    0) echo 'exit'
    ;;  
    1) echo 'A() script invoking here'
    ;;  
    *) echo 'B() script invoking here'
    ;;  
esac
0
MiniMax