it-swarm.com.de

Befehlszeile: Teilzeichenfolge aus der Ausgabe extrahieren

Sagen wir, ich führe den Befehl SayStuff aus

$ SayStuff

und die Ausgabe ist

Watermelons and cucumbers

Jetzt. Angenommen, ich möchte die Teilzeichenfolge cucumbers aus der Ausgabe extrahieren und in etwas umleiten.
Die Art und Weise, wie ich programmatisch vorgehen würde, wäre, die Ausgabe durch das Trennzeichen in ein Array aufzuteilen und es durch ArrayName[2] zu referenzieren. Ich bin ziemlich neu in Shell-Skripten und habe nur halbkryptische Beispiele für cut gefunden, von denen keines Sinn ergab.

Irgendwelche Ideen?

20
krystah
$ echo "Watermelons and cucumbers" | cut -d ' ' -f 3
cucumbers

Der -d ' ' weist cut an, nach Leerzeichen zu teilen. -f 3 wählt die dritte Spalte aus.

Sie können auch awk verwenden, wodurch die Aufteilung bereits auf der Grundlage des Speicherplatzes erfolgt und die Spalten als $1, $2, ... verfügbar gemacht werden.

$ echo "Watermelons and cucumbers" | awk '{ print $3 }'
cucumbers
29
slhck

Ich würde wahrscheinlich eine der Optionen verwenden, die bereits von @slhck angegeben wurden, aber hier sind einige weitere Möglichkeiten, dies zu tun:

  1. Verwenden von Arrays wie in jeder anderen Sprache:

    $ foo=( $(SayStuff) ) 
    $ echo ${foo[2]}
    cucumbers
    

    Die var=() deklariert ein Array, $(command) speichert die Ausgabe des Befehls. Also speichert foo=( $(SayStuff) ) die Ausgabe von SayStuff im Array foo und Sie dann echo es ist das dritte Element mit ${foo[2]}.

  2. sed

    $ SayStuff | sed 's/.* \(.*\)/\1/'
    cucumbers
    

    Der Befehl sed ersetzt (s///) alles mit dem letzten Wort. Der reguläre Ausdruck stimmt mit allem bis zu einem Leerzeichen (.*) überein, das mit allem bis zum letzten Leerzeichen übereinstimmt und dann den letzten Wort-(\(.*\) erfasst. Da das Wort erfasst wurde, können wir es als \1 bezeichnen.

    Eine einfachere Version:

    $ SayStuff | sed 's/.* //'
    cucumbers
    
  3. bash

    $ foo=$(SayStuff); echo ${foo##* } 
    cucumbers
    

    Dies nutzt die Manipulationsmöglichkeiten von Bash, siehe hier für weitere Details.

  4. Noch mehr Bash

    $ SayStuff | while read a b c; do echo $c; done
    cucumbers
    
  5. Perl, wo es natürlich viele Möglichkeiten gibt, dies zu tun:

    $ SayStuff | Perl -lane 'print $F[$#F]'
    cucumber
    

    Der -a bewirkt, dass sich Perl wie awk verhält, indem Zeilen mit Leerzeichen geteilt und im Array @F gespeichert werden. Wir drucken dann das letzte Element von @F ($#F ist die Anzahl der Elemente in @F). Der -l weist Perl an, jeder print -Anweisung eine neue Zeile hinzuzufügen, den -n, den STDIN zeilenweise verarbeiten soll, und den -e, der das in der Befehlszeile angegebene Skript ausführen soll.

    $ SayStuff | Perl -pe 's/.* //'
    cucumber
    

    Die Optionen wurden oben erklärt, wir löschen nur alles bis zum letzten Leerzeichen und drucken (-p).

    $ Perl -le 'print $ARGV[$#ARGV]' $(SayStuff)
    cucumbers
    

    Hier übergeben wir Watermelons and cucumbers als Argumente, die Perl im Array @ARG speichert, und drucken daher das letzte Element von @ARG.

  6. betrug. Dieser verwendet sed, um Leerzeichen in Zeilenumbrüche umzuwandeln, und dann tail, um nur die letzte Zeile zu drucken.

    $ SayStuff | sed 's/ /\n/g' | tail -n 1
    cucumbers
    
  7. grep und reguläre Ausdrücke mit -o, der nur die übereinstimmende Zeichenfolge ausgibt.

    $ SayStuff | grep -Po '\w+$' 
    cucumbers
    
  8. betrug

    $ SayStuff | grep -o cucumbers
    cucumbers
    
12
terdon

Hier ist noch eine Erklärung:

Usage: cut OPTION... [FILE]...

Print selected parts of lines from each FILE to standard output.

   -d, --delimiter=DELIM
          use DELIM instead of TAB for field delimiter

   -f, --fields=LIST
          select only these fields;  also print any line that contains  no
          delimiter character, unless the -s option is specified

Wenn Sie also das 3. Feld benötigen und es durch Leerzeichen '' begrenzt ist, ist es das

$ echo "Watermelons and cucumbers" | cut -d ' ' -f 3  
cucumbers

Wenn Sie das Feld LAST verwenden möchten, sollten Sie wahrscheinlich awk verwenden.
In diesem Fall wird es:

$ echo "Wassermelonen und Gurken" | awk '{print $ NF}'
Gurken

In awk NF ist die Anzahl der Felder in der Zeile, sodass $NF das letzte Feld in der Zeile bedeutet.

2
zeridon