Duplicated:Unix战争!Sed,Grep,Awk,Cut和Pulling组别跳出PowerShell常规表达捕获

[原文发表地址] Unix Fight! - Sed, Grep, Awk, Cut and Pulling Groups out of a PowerShell Regular Expression Capture

[原文发表时间] 2011-08-01 2:36PM

这是一个我说了多年的古老程序员的笑话了:

“你遇到一个问题,然后你决定用正则表达去解决。

好吧,那现在你就面临两个问题了……”

我的一个朋友在社交网站上说道:

“我耗费精力研究Windows世界的那十年阻碍了我的成长。一个小小的unix命令就会从XML文件中抓取我需要的值。”

现在,我把这个当做是一个个人挑战,从一个rit of fealous jage站起来,捍卫我的雇主。不过,和我在Nike围绕Unix工作数年还是有些不同的,我懂得了如何运用sed和awk,还有不要用什么。不过,他所说的是XML,好吧,PowerShell就会震撼XML的。

因为这是一个动态的语言,你可以像这样获取XML节点:

$a= ([xml](``new-objectnet.webclient).downloadstring(``"https://feeds.feedburner.com/Hanselminutes"``))

$a``.rss.channel.item

第一行获取反馈,第二行则获取所有的节点。

不过,结果是我的朋友事实上是在尝试从一个很大的SQL转储文件中的不怎么好的XML碎片中检索值。有三种XML,良好的,有效的和废弃的。他在废弃的XML中不停寻找一些值。总得来说他在其中有了这个含有一些XML碎片的疯狂文本文件,他想把值赋在元素之间:“<FancyPants>他想要这个值<FancyPants>。”

就像这样:

grep ``"<FancyPants>.*<.FancyPants>" test.txt | sed -e ``"s/^.*<FancyPants/<FancyPants/"| cut -f2 -d``">"``| cut -f1 -d``"<"> fancyresults.txt

我的确有经验,不过我不是grep和sed的专家,所以我想他应该有办法可以更好地做到这点的。办法总是有的,不是吗?有了正则表达式,人们有时只需输入$@($*@)$(*@)(@*)@*(%@%#,然后莎士比亚就跳出来了。你从不会知道会发生什么。

在PowerShell里还有很多不同的方法可以做到这点,不过既然他用的是RegExes,我又怎么能有异议呢?

首先,这是一行的答案。

cat test.txt | ``foreach-object{``$null = $_ ``-match'<FancyPants>(?<x>.*)<.FancyPants>'`` ; ``$matches``.x}

不过我觉得我会帮他们分类整理一下,去除一些冗余。

cat test.txt | ``foreach-object{``$null = $_ ``-match'<FancyPants>(?<x>.*)<.FancyPants>'`` ; ``$matches`` .x} | ``sort | ``get-unique

不过遍历循环对象还有个别名:%,例如get-unique的别名是”gu”.所以最终的结果是:

cattest.txt | % {``$null = $_ ``-match'<FancyPants>(?<x>.*)<.FancyPants>'``;``$matches`` .x} | ``sort | ``gu

我想我们可以达成一致的是,无论是哪种,都很难读。我还是比较偏爱PowerShell