【问题标题】:Handling metacharacters in search strings处理搜索字符串中的元字符
【发布时间】:2010-01-25 20:55:25
【问题描述】:

我有一个用户输入将用于可能包含元字符的搜索字符串

例如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'`

但它不能正常工作。 或者有没有其他方法可以使用元字符来处理用户输入?

提前致谢

【问题讨论】:

  • 您是如何获得用户输入的?作为命令行参数还是通过read 命令?
  • 有趣。使用您的新示例,C++ 是给我带来麻烦的一个,它似乎是 C# 对您来说有问题。我发现使用 both 引号和反斜杠会有所帮助:grep -E "C\+\+" 就像使用带有转义管道的常规 grep 而不逃避加号一样:grep "C++\|C#"
  • 关于您的 sed 示例,您通常不希望在赋值左侧的变量名称上使用美元符号(除非您正在执行间接操作)。
  • 这两个变量需要在同一行中才能被找到,并且按照顺序 $1 先然后 $2 有人指出 awk 可能会起作用,我想我去读一下。希望这是正确的方法,顺便说一句,谢谢你帮助我:)

标签: bash variables grep user-input special-characters


【解决方案1】:

如果您将输入作为参数传递给脚本

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

【讨论】:

  • 我用以下代码尝试了两个变量:fileContents = cat BookDB.txt; fileContents 中的 case "$1*$2" ) echo "found!";; esac 根本找不到任何东西 我将输入作为参数传递给脚本 抱歉,我不知道如何在 cmets 中格式化代码。它看起来很凌乱.. >.
  • 查看新编辑。不需要猫。只需使用 shell 执行一个 while 读取循环。
【解决方案2】:

这对我有用:

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

编辑:

您可以在没有-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#

【讨论】:

  • 它确实有效,但不适用于两个变量。我意识到我的 grep 语句是错误的。现在已更正,但仍无法处理带有元字符的字符串 :(
【解决方案3】:

只需在 $1 和 $2 中引用所有 grep 元字符,然后再将它们添加到您的 grep 表达式中。

类似这样的:

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

应该可以工作。调整 metachar 列表以适应。处理 |有点棘手,因为反斜杠 使它很特别,但由于我们已经在反斜杠上,所以我认为它是安全的。

【讨论】:

  • 我注意到封闭的\(和\)中有两个[],添加第二个的目的是什么?在替换字符串中,我只了解 3 \, 2 的目的是制作第一个附加在前面的反斜杠,最后一个表示 \1。最后两个是干什么用的?
猜你喜欢
  • 2016-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多