PS C:/PowerShell/test1> gc passwd s2002408030068:x:527:527::/home/dz02/s2002408030068:/bin/pw s2002408032819:x:528:528::/home/dz02/s2002408032819:/bin/pw s2002408032823:x:529:529::/home/dz02/s2002408032823:/bin/pw
PS C:/PowerShell/test1> gc shadow s2002408030068:$1$d8NwFclG$v4ZTacfR2nsbC8BnVd3dn1:12676:0:99999:7::: s2002408032819:$1$UAvNbHza$481Arvk1FmixCP6ZBDWHh0:12676:0:99999:7::: s2002408032823:$1$U2eJ3oO1$bG.eKO8Zupe0TnyFhWX9Y.:12676:0:99999:7::: |
我们希望用shadow中第二个域中的字符串替换passwd中的第二个域的'x'. 代码示例如下:
PS C:/PowerShell/test1> gc shadow | %{ $hash = @{} } { $key,$value = $_.trim().split(':')[0,1]; $hash.$key = $value } |
我们初始化了一个名称为hash的HashTable, 接下来用了一个perl的多值赋值语句将我们需要信息用数组slice技巧赋值, 最后添加到hash中. 貌似分割太复杂了, sigh...接下来,我们还要将这些数据与passwd中的信息进行合并.
PS C:/PowerShell/test1> switch -f passwd { { $_ -notmatch '^/s*$' } { $ofs = ":"; $input = $_.split(':'); $input[1] = $hash[$input[0]]; "$input" } } s2002408030068:$1$d8NwFclG$v4ZTacfR2nsbC8BnVd3dn1:527:527::/home/dz02/s2002408030068:/bin/pw s2002408032819:$1$UAvNbHza$481Arvk1FmixCP6ZBDWHh0:528:528::/home/dz02/s2002408032819:/bin/pw s2002408032823:$1$U2eJ3oO1$bG.eKO8Zupe0TnyFhWX9Y.:529:529::/home/dz02/s2002408032823:/bin/pw |
完成任务, 不过我确实用了很多代码, 看起来很复杂. 这里我特意使用了强大的switch来操作文件, 分支条件也使用了表达式.
写到这里, 我觉得很郁闷, 如果我们能获得awk默认的特性, 设置一些默认的变量, 那么我就会更加简单了.
***********************************
我最终决定, 扩展自己的哦PowerShell, 完成一些令人crazy的事情. 让PowerShell具有awk的能力. 以下代码绝对原创:
***********************************
filter awk ([scriptblock] $cmd = $args[0], [regex] $delimiter='/s+') { $line = @(); $nf = 0; $line = @($delimiter.split($_.Trim())); $nf = $line.length; $0 = $_; for ($i = 1; $i -le $nf; $i++) { Invoke-Expression "`$$i = '$($line[$i - 1])'" } & $cmd } |
好了, 虽然他还不能算得上好使, 但是一般工作都可以完成了. 下面我们测试一下他. 目前他只能支持从管道读取数据.
2. 连接两个文件, 连接属性是某个域上的字串
我们先看下输入数据:
PS C:/PowerShell/test2> gc file1 0011AAA 200.00 20050321 0012BBB 300.00 20050621 0013DDD 400.00 20050622 0014FFF 500.00 20050401 PS C:/PowerShell/test2> gc file2 I0011 11111 I0012 22222 I0014 55555 I0013 66666 |
我们需要根据file1中第一个域上前4个字符和file2上第一个域的2到5个字符进行比较. 将file2第二个域的数据连接到file1上. 我们来测试下awk的功能吧:
PS C:/PowerShell/test2> $hash = @{} PS C:/PowerShell/test2> gc file2 | awk -cmd {$hash[$1.substring(1,4)] = $2} PS C:/PowerShell/test2> gc file1 | awk -cmd { "$0 $($hash[$1.substring(0,4)])" } 0011AAA 200.00 20050321 11111 0012BBB 300.00 20050621 22222 0013DDD 400.00 20050622 66666 0014FFF 500.00 20050401 55555 |
OK了, 是不是简单了很多呢??
在下一次中, 我将会继续完成3,4题. 希望, 今天的例子足以让你感受到PowerShell的强大. awk 大约花费了我30分钟的时间. 这种扩展带来了更加快速的处理效率.