Обработка метасимволов в строках поиска - PullRequest
0 голосов
/ 25 января 2010

У меня есть пользовательский ввод, который будет использоваться в строке поиска, которая может содержать метасимвол

Например, C # или C ++

моя команда grep в функции была:

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

при прямой замене:

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

первый отлично поймал строки, но не второй. Странно, но # был полностью проигнорирован. Без прямой замены оба перехватывают что-либо с помощью c, за которым следует testWord вместо c ++ и c # соответственно

Я пытался справиться с этим с помощью sed

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

но это не работает правильно. Или есть какой-то другой способ обработки пользовательского ввода с метасимволами?

Заранее спасибо

Ответы [ 3 ]

0 голосов
/ 26 января 2010

если вы передаете входные данные в качестве аргументов скрипту

#!/bin/bash

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

"

выход

$ 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

если вы получаете ввод от чтения

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 голосов
/ 26 января 2010

Просто заключите все метасимволы grep в $ 1 и $ 2, прежде чем добавлять их в выражение grep.

Примерно так:

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

должно работать. Настройте список метачаров, чтобы удовлетворить. Обработка | это немного сложно, потому что обратная косая черта делает особенной, но, поскольку мы уже имеем обратную косую черту, я думаю, что это безопасно.

0 голосов
/ 26 января 2010

Это работает для меня:

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

Edit:

Вы можете попробовать эту форму без -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#
...