Share via


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 14:36

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

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

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

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

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

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

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

    1: $a = ([xml](new-object net.webclient).downloadstring("https://feeds.feedburner.com/Hanselminutes"))
    2: $a.rss.channel.item
    3:  

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

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

就像这样:

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

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

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

首先,这是一行的答案。

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

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

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

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

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

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