2010-01-25 3 views
0

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

Для получения, например, C# или C++

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

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

под прямой замены:

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

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

Я попытался его обработки с использованием СЭД

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

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

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

+0

Как вы получаете вход пользователя? Как аргументы командной строки или с помощью команды 'read'? –

+0

Интересно. Используя ваши новые примеры, C++ - это тот, который дает мне проблемы, когда это похоже на C#, что для вас проблематично. Я обнаружил, что использование ** обоих ** котировок и обратных косых черт помогло: 'grep -E" C \ + \ + "', как и с использованием регулярного grep с экранированным контуром, не избегая плюсов: 'grep 'C++ \ | C#" ' –

+0

Что касается вашего примера sed, обычно вы не хотите, чтобы знак доллара указывал на имя переменной в левой части задания (если вы не делаете косвенное действие). –

ответ

0

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

#!/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

Я попытался с двумя переменными с помощью следующего кода: fileContents = кошка BookDB.t; случая «* $ 1 * $ 2 *» в * fileContents *) echo "found!" ;; esac ничего не смог найти Я передавал входной файл в качестве аргументов скрипту Извините, я не знаю, как форматировать код в комментариях. Это выглядит довольно грязно ..>. < – eruina

+0

см. Новое редактирование. нет необходимости в кошке. просто сделайте цикл чтения, используя оболочку. – ghostdog74

0

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

$ 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# 
+0

Он работает, но не с двумя переменными. Я понял, что мое заявление grep было неправильным. Это исправлено теперь, но все еще не в состоянии обрабатывать строки с метасимволами :( – eruina

0

Просто процитирую все 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 

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

+0

Я заметил два [] в прилагаемых \\ (и \\), для чего нужно добавить второй? и в заменяющей строке я понял только цель 3 \, 2, чтобы сделать первую обратную косую черту, которая будет добавлена ​​спереди, а последняя будет представлять \ 1. для чего будут последние два? – eruina

Смежные вопросы