grep su una variabile


58

Diciamo che ho una variabile

line="This is where we select from a table."

ora voglio grep quante volte selezionare si verifica nella frase.

grep -ci "select" $line

Ci ho provato, ma non ha funzionato. Ho anche provato

grep -ci "select" "$line"

Non funziona ancora. Ottengo il seguente errore.

grep: This is where we select from a table.: No such file or directory

1
Devi usare herestring ...<<<"$line" . Il comando grepprevede invece un file
Valentin Bajrami,

Risposte:


85

Ho grepletto sul suo input standard. Ecco qua, usando una pipa ...

$ echo "$line" | grep select

... o una stringa qui ...

$ grep select <<< "$line"

Inoltre, potresti voler sostituire gli spazi con le nuove righe prima del grepping:

$ echo "$line" | tr ' ' '\n' | grep select

... oppure potresti chiedere grepdi stampare solo la corrispondenza:

$ echo "$line" | grep -o select

Questo ti permetterà di sbarazzarti del resto della linea quando c'è una partita.

Modifica: Ops, leggi un po 'troppo in fretta, grazie Marco . Per contare le occorrenze, basta semplicemente eseguire il pipe di uno di questi a wc(1);)

Un'altra modifica fatta dopo il commento di lzkata , citando $linequando si usa echo.


3
Poiché l'OP vuole contare il numero di occorrenze di una stringa, è possibile aggiungere un wcper completare l'attività:grep -o <string> <<< "$variable" | wc -l
Marco,

2
Usa echo "$line"per preservare le nuove linee esistenti invece di crearne contr
Izkata,

Qual è la disponibilità di una stringa Here? Richiede Bash o un'altra shell?

Secondo Wikipedia , qui le stringhe sono disponibili in bash, ksh e zsh (ma suppongo che potrebbero essercene altre).
John WH Smith,

7
test=$line i=0
while case "$test" in (*select*)
test=${test#*select};;(*) ! :;;
esac; do i=$(($i+1)); done

Non è necessario chiamare grepper una cosa così semplice.

O come una funzione:

occur() while case "$1" in (*"$2"*) set -- \
        "${1#*"$2"}" "$2" "${3:-0}" "$((${4:-0}+1))";;
        (*) return "$((${4:-0}<${3:-1}))";;esac
        do : "${_occur:+$((_occur=$4))}";done

Ci vogliono 2 o 3 argomenti. Fornire qualcosa di più di questo altera i suoi risultati. Puoi usarlo come:

_occur=0; occur ... . 2 && echo "count: $_occur"

... che stampa il conteggio delle occorrenze di .in ...se si verifica almeno 2 volte. Come questo:

count: 3

Se $_occurè vuoto o unsetquando viene invocato, non avrà alcun effetto sulle variabili shell e return1 se si "$2"verifica in "$1"meno di "$3"volte. Oppure, se chiamato con solo due argomenti, return1 sarà solo se "$2"non è in "$1". Altrimenti restituisce 0.

E così, nella sua forma più semplice, puoi fare:

occur '' . && echo yay || echo shite

... che stampa ...

shite

...ma...

occur . . && echo yay || echo shite

... stamperà ...

yay

Potresti anche scriverlo in modo leggermente diverso e omettere le virgolette $2in entrambe le istruzioni (*"$2"*)e "${1#*"$2"}". Se lo fai, puoi usare i globs di shell per le partite come sh[io]teper il test delle partite.


1
+1: più veloce, davvero. Funziona in bashe dash/ sh(e probabilmente alcuni altri).
John WH Smith,

@JohnWHSmith - la modifica è migliore, ma comunque altrettanto portatile.
Mikeserv,
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.