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。