grep on unix / linux:如何replace或者捕获文本?

所以我用正则expression式很好,但是我在unix上遇到了一些麻烦。 这里有两件事我很想知道该怎么做:

1) replace除字母,数字和下划线以外的所有文本

在PHP中,我会这样做:(工程很好)

 preg_replace函数( '#[^ A-ZA-Z0-9 _]#', '',$文本)。

在bash中我尝试了这个(有限的成功); 似乎它不允许你使用整套正则expression式:

 text =“我的#1例子!”
 $ {文本/ [^ A-ZA-Z0-9 _] / '')

我试着用sed,但它似乎仍然有问题的完整正则expression式集:

 回声“我的#1例子!”  |  sed s / [^ a-zA-Z0-9 \ _] //

我敢肯定有一种方法可以用grep来做,但是当我尝试的时候会把它分成多行:

  echo abc \!\ @ \#\ $ \%\ ^ \&\ * \(222 | grep -Eos'[a-zA-Z0-9 \ _] +' 

最后我也尝试使用expr,但它似乎是真正有限的扩展正则expression式的支持…


2) 捕获(多个)文本部分

在PHP中,我可以做这样的事情:

的preg_match( '#(字1)*(字词)#',$文本,$匹配);

我不确定在* nix中怎么可能…

第1部分

你差不多和sed刚刚添加g修饰符,这样全局替换就发生了,没有g ,替换就只发生一次。

 $ echo "my #1 example!" | sed s/[^a-zA-Z0-9\_]//g my1example $ 

你也对你的bash模式替换做了同样的错误:没有在全球进行替换:

 $ text="my #1 example!" # non-global replacement. Only the space is delete. $ echo ${text/[^a-zA-Z0-9_]/''} my#1 example! # global replacement by adding an additional / $ echo ${text//[^a-zA-Z0-9_]/''} my1example 

第2部分

捕获在sed工作方式与在PHP的正则表达式中一样:将括号括起来触发捕获:

 # swap foo and bar's number using capturing and back reference. $ echo 'foo1 bar2' | sed -r 's/foo([0-9]+) bar([0-9]+)/foo\2 bar\1/' foo2 bar1 $ 

作为使用sed codaddict很好的答案的替代方法,你也可以用tr来表示你的问题的第一部分。

 echo "my #1 _ example!" | tr -d -C '[[:alnum:]_]' 

我也使用了[:alnum:]字符类,只是为了显示另一个选项。

你是什​​么意思,你不能使用bash的正则表达式语法?

 $ text="my #1 example!" $ echo ${text//[^a-zA-Z0-9_]/} my1example 

你必须使用/ /超过1替换。

为你的第二个问题,用bash 3.2 ++

 $ [[ $text =~ "(my).*(example)" ]] $ echo ${BASH_REMATCH[1]} my $ echo ${BASH_REMATCH[2]} example