2010-01-25 15 views
0

j'ai une entrée utilisateur qui serait utilisé dans une chaîne de recherche qui peut contenir un métacaractèreManipulation métacaractères dans les chaînes de recherche

Pour exemple C# ou C++

ma commande grep en fonction était:

grep -E "$1|$2" test.txt 

en remplacement direct:

grep -E "C\+\+|testWord" test.txt 
grep -E "C\#|testWord" test.txt 

le premier pris les lignes fines, mais pas la seconde. Etrangement, # a été complètement ignoré. Sans remplacement direct, à la fois attraper quoi que ce soit avec c suivi par Testword au lieu de C++ et C# respectivement

J'ai essayé manipuler avec sed

$temp = `echo $1 | sed 's/[\#\!\&\;\`\"\'\|\*\?\~\<\>\^\(\)\[\]\{\}\$\+\\]/\\&/g'` 

mais il ne fonctionne pas bien. Ou existe-t-il un autre moyen de gérer les entrées utilisateur avec des métacaractères?

Merci à l'avance

+0

Comment obtenez-vous l'entrée de l'utilisateur? Comme arguments de ligne de commande ou via la commande 'read'? –

+0

Intéressant. En utilisant vos nouveaux exemples, C++ est celui qui me donne le problème où il semble que C# est problématique pour vous. J'ai trouvé que l'utilisation des guillemets ** et des backslashes ** aidait: 'grep -E" C \ + \ + "' comme le fait d'utiliser grep avec un tube échappé sans échapper les plus: 'grep 'C++ \ | C#" ' –

+0

En ce qui concerne votre exemple de sed, vous ne voulez normalement pas un signe dollar sur un nom de variable sur le côté gauche d'une affectation (sauf si vous faites de l'indirection). –

Répondre

0

si vous passez la contribution en tant qu'arguments à la scénario

#!/bin/bash 

input1="$1" 
input2="$2" 
while read -r line 
do 
    case "$line" in 
     *$input1*|*$input2*) echo "found: $line";; 
    esac 
done <"BooksDB.txt 

"

sortie

$ cat file 
this is a line 
this line has C++ and C# 
this line has only C++ and that's it 
this line has only C# and that's it 
this is end line Caa 

$ ./shell.sh C++ C# 
found: this line has C++ and C# 
found: this line has only C++ and that's it 
found: this line has only C# and that's it 

si vous obtenez l'entrée de lecture

read -p "Enter input1:" input1 
read -p "Enter input2:" input2 
while read -r line 
do 
    case "$line" in 
     *$input1|*$input2*) echo "found: $line";; 
    esac 
done <"BooksDB.txt" 
+0

J'ai essayé avec deux variables avec le code suivant: fileContents = cat BookDB.txt, cas « * $ 1 * 2 * $ » dans * fileContents *) echo "trouvé!" ;; esac Je ne trouvais rien du tout Je passais l'entrée theh comme arguments au script Désolé, je ne sais pas comment mettre en forme le code dans les commentaires. Il semble assez malpropre ..>. < – eruina

+0

voir nouvelle édition. pas besoin de chat. Il suffit de faire une boucle de lecture en utilisant le shell. – ghostdog74

0

Cela fonctionne pour moi:

$ testfun1(){ echo "foo $1" | grep "$1"; } 
$ testfun1 C# 
foo C# 
$ testfun2(){ read a; echo "bar $a" | grep "$a"; } 
$ testfun2 
C# 
bar C# 

Edit:

Vous pouvez essayer ce formulaire sans -E:

$ testfun3(){ grep "$1\|$2" test.txt; } 
$ testfun3 C++ awk 
something about C++ 
blah awk blah 
$ testfun3 C# sed 
blah sed blah 
the text containing C# 
$ testfun3 C# C++ 
something about C++ 
the text containing C# 
+0

Cela fonctionne mais pas avec deux variables. J'ai réalisé que ma déclaration grep était erronée. Il est maintenant corrigé mais est toujours incapable de gérer les chaînes avec métacaractères :( – eruina

0

citer que tous les grep métacaractères de 1 $ et 2 $ avant de les ajouter à votre expression grep.

Quelque chose comme ceci:

quoted1=`echo "$1" | sed -e 's/\([]\.?^${}+*[]\)/\\\\\1/g'` 
quoted2=`echo "$2" | sed -e 's/\([]\.?^${}+*[]\)/\\\\\1/g'` 
grep -E "$quoted1\|$quoted2" test.txt 

devrait fonctionner. Ajustez la liste de métachar pour convenir. Manutention | est un peu difficile parce que backslashing rend spécial, mais puisque nous sommes déjà backslashing backslash je pense que c'est en sécurité.

+0

J'ai remarqué deux [] dans le \\ (et \\) ci-joint, quel est le but de l'ajout du second? et dans la chaîne de remplacement, j'ai seulement compris le but de 3 \, 2 de faire la première barre oblique qui serait ajoutée à l'avant, la dernière représentant \ 1. à quoi serviraient les deux derniers? – eruina