grep sur une variable

58

Disons que j'ai une variable

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

Maintenant, je veux dire combien de fois la phrase est sélectionnée.

grep -ci "select" $line

J'ai essayé ça, mais ça n'a pas marché. J'ai aussi essayé

grep -ci "select" "$line"

Cela ne fonctionne toujours pas. Je reçois l'erreur suivante.

grep: This is where we select from a table.: No such file or directory
gkmohit
la source
1
Vous devez utiliser herestring ...<<<"$line" . La commande grepattend un fichier à la place
Valentin Bajrami
stackoverflow.com/questions/2106526/…
Ciro Santilli a commencé à jouer

Réponses:

85

J'ai greplu sur son entrée standard. Voilà, en utilisant une pipe ...

$ echo "$line" | grep select

... ou une chaîne ici ...

$ grep select <<< "$line"

Aussi, vous voudrez peut-être remplacer les espaces par des nouvelles lignes avant grepping:

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

... ou vous pouvez demander grepd'imprimer le match uniquement:

$ echo "$line" | grep -o select

Cela vous permettra de vous débarrasser du reste de la ligne quand il y a correspondance.

Edit: Oups, lisez un peu trop vite, merci Marco . Pour compter les occurrences, il suffit d’en diriger l’une d’elles vers wc(1);)

Une autre édition faite après le commentaire de lzkata , citant $linelors de l’utilisation echo.

John WH Smith
la source
3
Puisque l'OP veut compter le nombre d'occurrences d'une chaîne, vous pouvez ajouter un wcpour compléter la tâche:grep -o <string> <<< "$variable" | wc -l
Marco
2
Utilisez cette echo "$line"tr
option
Quelle est la disponibilité d'une chaîne Here? Cela nécessite-t-il Bash ou un autre shell?
Selon Wikipedia , ici les chaînes sont disponibles en bash, ksh et zsh (mais je suppose qu'il peut y en avoir d'autres).
John WH Smith
7
test=$line i=0
while case "$test" in (*select*)
test=${test#*select};;(*) ! :;;
esac; do i=$(($i+1)); done

Vous n'avez pas besoin d'appeler greppour une chose aussi simple.

Ou en fonction:

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

Il faut 2 ou 3 arguments. Fournir plus que cela faussera ses résultats. Vous pouvez l'utiliser comme:

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

... qui affiche le nombre d'occurrences .dans ...s'il se produit au moins 2 fois. Comme ça:

count: 3

Si $_occurest vide ou unsetlorsqu'il est appelé, cela n'affectera aucune variable shell et return1 si "$2"survient "$1"moins de "$3"fois. Ou, si elle est appelée avec seulement deux arguments, elle ne sera return1 que si elle "$2"n’est pas insérée "$1". Sinon, il retourne 0.

Et ainsi, dans sa forme la plus simple, vous pouvez faire:

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

... qui imprime ...

shite

...mais...

occur . . && echo yay || echo shite

... imprimera ...

yay

Vous pouvez également l'écrire un peu différemment et omettre les guillemets $2dans l' instruction (*"$2"*)and "${1#*"$2"}". Si vous faites cela, vous pouvez utiliser des globes de shell pour les correspondances comme sh[io]tepour le test de correspondance.

Mikeserv
la source
1
+1: plus rapide, en effet. Fonctionne dans bashet dash/ sh(et probablement quelques autres).
John WH Smith
@JohnWHSmith - le montage est meilleur, mais toujours aussi portable.
mikeserv