Riga di comando: estrae la sottostringa dall'output


25

Di 'che eseguo il comando SayStuff

$ SayStuff

e l'output è

Watermelons and cucumbers

Adesso. Supponiamo che io voglia estrarre la sottostringa cucumbersdall'output e inserirla in qualcosa.
Il modo in cui farei questo a livello di codice sarebbe quello di dividere l'output in un array dal delimitatore Space e fare riferimento a esso ArrayName[2]. Sono abbastanza nuovo con gli script di shell e sono riuscito solo a trovare cutesempi semi-criptici , nessuno dei quali aveva senso.

Qualche idea?

Risposte:


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

Il -d ' 'dice cutdi dividere sugli spazi. -f 3seleziona la terza colonna.

È inoltre possibile utilizzare awk, che fa la suddivisione in base allo spazio già e rende le colonne disponibili $1, $2...

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

Nota che cutnon gestirà un numero variabile di spazi, mentre lo awkfai.
Zitrax,

13

Probabilmente userei una delle opzioni già fornite da @slhck ma qui ci sono alcuni altri modi per farlo:

  1. Usando le matrici, come faresti in qualsiasi altra lingua:

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

    L' var=()dichiara un array, $(command)salva l'output del comando. Quindi, foo=( $(SayStuff) )memorizza l'output di SayStuffnell'array fooe quindi echoè il terzo elemento con ${foo[2]}.

  2. sed

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

    Il sedcomando sostituirà ( s///) tutto con l'ultima parola. La regex corrisponde a qualsiasi cosa fino a uno spazio ( .*) che corrisponderà a tutto fino all'ultimo spazio e quindi acquisisce l'ultima parola (\(.*\). Poiché la parola è stata catturata, possiamo fare riferimento ad essa come \1.

    Una versione più semplice:

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

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

    Questo utilizza le abilità di manipolazione delle stringhe di bash, vedi qui per maggiori dettagli.

  4. Più bash

    $ SayStuff | while read a b c; do echo $c; done
    cucumbers
  5. Perl, dove ovviamente ci sono molti modi per farlo:

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

    Le -amarche si perlcomportano come awk, suddividendo le linee negli spazi bianchi e salvando nell'array @F. Quindi stampiamo l'ultimo elemento di @F( $#Fè il numero di elementi in @F). La -ldice a Perl di aggiungere un ritorno a capo ad ogni printdichiarazione, il -nche dovrebbe elaborare linea STDIN per riga e -eche dovrebbe eseguire lo script data dalla riga di comando.

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

    Le opzioni sono state spiegate sopra, stiamo eliminando tutto fino all'ultimo spazio e stampando ( -p).

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

    Qui stiamo passando Watermelons and cucumberscome argomenti, che perl salverà @ARGnell'array e quindi, stampiamo l'ultimo elemento di @ARG.

  6. inganno. Questo utilizza sedper convertire gli spazi in newline e quindi tailper stampare solo l'ultima riga.

    $ SayStuff | sed 's/ /\n/g' | tail -n 1
    cucumbers
  7. grep ed espressioni regolari, usando le -oquali stampa solo la stringa corrispondente.

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

    $ SayStuff | grep -o cucumbers
    cucumbers

2

Ecco qualche spiegazione in più:

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

Quindi se hai bisogno del terzo campo ed è delimitato da spazi '', allora lo è

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

Se vuoi il campo ULTIMO probabilmente dovresti usare awk .
In questo caso diventa:

$ echo "Angurie e cetrioli" | awk "{print $ NF}"
cetrioli

In awkNF è il numero di campi nella riga, quindi $NFsignifica l'ultimo campo nella riga.


fondamentalmente la stessa domanda è qui ma più generalizzata: stackoverflow.com/questions/3162385/… Sì, puoi usare altri modi ma awk è il più breve
zeridon,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.