[英]Command-line tool to extract strings using regex
对于三个受污染的RE的每一个完全任意的集合,即“ re1 ( re2 ) re3 ”,我想要一个工具(或单线 )输出与re2匹配的所有内容。 ( \\1
)
我正在寻找一种通用的命令行工具,该工具将使用任意正则表达式(如grep -o
提取信息,但要具有上下文意识,如expr match
。 我希望在grep -o
使用的功能是在文件上进行迭代,并且仅打印匹配项, 但我不想打印出上下文。 我想要在expr match
中使用的功能是能够从上下文中提取内容(即,提取子表达式)。 基本上,我想匹配每个子表达式并仅将其打印出来。
注意:以下仅是一个简单示例。 我的问题是一个笼统的问题,涉及从引用材料到提取XML标签的所有问题,您可以为其编写正则表达式的任何问题。 ERE很好,PCRE更好。
例如,假设我要打印出括号内的一行中的所有内容,但不想打印括号。 如果我执行grep -Eo '([^()]*?)'
我会得到所有匹配项,但是它们周围都有括号:
输入:
$ grep -Eo '\([^()]*?\)'
foo (bar) baz (bat)
输出:
(bar)
(bat)
正确:两个孤立的项目。 错误的:他们有括号。
或者我可以使用expr match
:
$ expr match 'foo (bar) baz (bat)' '.*(\([^()]*\)).*'
这给了我:
bat
正确地删除了括号,但是错过了第一次出现。
我想过在sed
该怎么做; 一个人可以使用替换,但是sed
像expr match
这样吃掉第一个出现的东西:
$ echo 'foo (bar) baz (bat)' | sed 's/.*(\([^()]*\)).*/\1/g'
bat
此外,我不认为sed
旨在从一行输入生成两行或更多行输出(就像grep -o
一样); 它更像是逐行工具。 如果sed
可以选择将\\
n子表达式匹配项放入模式空间或保持有效的空间。
我认为这可能在gawk
可行,但似乎并不简单。 像sed
一样, gawk
可以进行替换; 像grep
一样,它可以匹配子字符串; 像expr match
,它在一行中有多个引用存在麻烦(尽管与expr match
不同,它有很多解决方法)。
它可能可以在Perl中完成,但是会涉及某种复杂的循环。
通过查看许多相关的SO问题,许多解决方案针对特定问题的特定特征做出了答复,但是我想要一个通用的解决方案。
如果您有gnu grep,则可以使用先行提示一步完成此操作:
s='foo (bar) baz (bat)'
grep -Po '(?<=\()[^()]*(?=\))' <<< "$s"
bar
bat
或使用gnu awk:
awk -v FPAT='\\([^()]*\\)' '{for (i=1; i<=NF; i++) {gsub(/[()]/, "", $i); print $i}}' <<< "$s"
bar
bat
或使用sed:
sed -E 's/[^()]*\(([^()]*)\)/\1:/g' <<< "$s"
bar:bat:
受sendmail
*的启发,我认为也许只有两步的过程可能会起作用,而只有一步却没有。 解决方案很简单; 使用grep -o
打印出匹配项,并使用sed
删除不需要的上下文:
$ re='\(([^()]*)\)'; echo 'foo (bar) baz (bat)' | grep -Eo "$re" | sed -r "s/$re/\1/1"
bar
bat
$ re="<([^<>]*)>"; echo "I <strong>really</strong> want <A href="http://foo.com">this</A>" | grep -Eo "$re" | sed -r "s/$re/\1/1"
strong
/strong
A href=http://foo.com
/A
$ re="<[^<>]*>([^<]*)<[^<>]*>"; echo "I <strong>really</strong> want <A href="http://foo.com">this</A>" | grep -Eo "$re" | sed -r "s/$re/\1/1"
really
this
$ re="'([^']*)'"; echo "His name was 'John', her name was 'Jane'" | grep -Eo "$re" | sed -r "s/$re/\1/1"
John
Jane
您只需要在正则表达式中转义任何斜线或执行某些操作来解决sed
分隔符问题。
* sendmail
,或者不如说是来与宏sendmail
,有这种非同寻常的技术(所谓的“重点”)的内部清理的电子邮件地址,并临时增加多余的语法,使他们更容易处理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.