grep em uma variável

44

Digamos que eu tenha uma variável

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

agora quero grep quantas vezes o select ocorre na sentença.

grep -ci "select" $line

Eu tentei isso, mas não funcionou. Eu também tentei

grep -ci "select" "$line"

Ainda não funciona. Estou tendo o erro a seguir.

grep: This is where we select from a table.: No such file or directory
    
por gkmohit 23.10.2014 / 17:24

2 respostas

66

Tenha grep lido em sua entrada padrão. Lá vai você, usando um cachimbo ...

$ echo "$line" | grep select

... ou uma string aqui ...

$ grep select <<< "$line"

Além disso, você pode querer substituir espaços por novas linhas antes do grepping:

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

... ou você pode pedir ao grep para imprimir apenas a correspondência:

$ echo "$line" | grep -o select

Isso permitirá que você se livre do restante da linha quando houver uma correspondência.

Editar: Ops, leia um pouco rápido demais, obrigado Marco . Para contar as ocorrências, basta enviar qualquer uma delas para wc(1) ;)

Outra edição feita após o comentário de lzkata , citando $line ao usar echo .

    
por 23.10.2014 / 17:32
6
test=$line i=0
while case "$test" in (*select*)
test=${test#*select};;(*) ! :;;
esac; do i=$(($i+1)); done

Você não precisa chamar grep para uma coisa tão simples.

Ou como uma função:

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

Leva 2 ou 3 args. Fornecer mais do que isso distorcerá seus resultados. Você pode usá-lo como:

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

... que imprime a contagem de ocorrências de . em ... se ocorrer pelo menos 2 vezes. Assim:

count: 3

Se $_occur estiver vazio ou unset quando for invocado, isso não afetará nenhuma variável do shell e return 1 se "$2" ocorrer em "$1" less de "$3" times. Ou, se chamado com apenas dois argumentos, ele return 1 somente se "$2" não estiver em "$1" . Senão retorna 0.

E assim, na sua forma mais simples, você pode fazer:

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

... que imprime ...

shite

... mas ...

occur . . && echo yay || echo shite

... vai imprimir ...

yay

Você também pode escrever um pouco diferente e omitir as aspas em torno de $2 na instrução (*"$2"*) e "${1#*"$2"}" . Se você fizer isso, poderá usar shell globs para correspondências como sh[io]te para o teste de correspondência.

    
por 23.10.2014 / 18:14