我正在尝试使用Perl单行来从grepping svn diff中获取一些输出,因此我可以自动测试文件。我们有一个run_test.sh脚本,它可以使用前面带有'Test'作为参数的多个PHP文件。
到目前为止,我有以下成功将'Test'添加到文件名
的内容[gjempty@gjempty-rhel4 classes]$ svn diff | grep '(revision' | perl -wpl -e 's/(.*)\/(.*)$/$1\/Test$2/'
--- commerce/TestLCart.php (revision 104387)
--- commerce/manufacturing/TestLRoutingData.php (revision 104387)
现在我只想抓取文件/路径将其传递给我们的run_test.sh。我可以用awk完成它,如下所示,但我正在努力提高我的Perl /单线技能。那么如何修改perl单行以仅另外提取文件路径?
svn diff | grep '(revision' | perl -wpl -e 's/(.*)\/(.*)$/$1\/Test$2/' | awk '{print $2}' | xargs run_test.sh
答案 0 :(得分:4)
你只是想要文件名,所以svn st
就是你想要的。您可以这样得到:(revision
,而不是获得可能包含M commerce/LCart.php
的大量噪音以及您想要的主线。然后你可以砍掉\S*
(任意数量的非空格字符),然后是\s*
(任意数量的空格字符),然后选择剩下的字符。您可以采用不同的方式进行\S*\s*
,但这是获取所有案例的最简单方法。
svn st | perl -wpl -e 's|\S*\s*(.*)/(.*)$|$1/Test$2|'
(从使用s ///发送到s |||之后切换它,所以/不需要转义;好主意,Axeman。)
答案 1 :(得分:3)
你可以很容易地摆脱grep
和awk
。
svn diff | perl -wnl -e '/\(revision/ or next; m|(\S+)/(\S+)|; print "$1/Test$2";'
我将-p更改为-n。 -p表示while (<>) { <your code>; print $_; }
,-n相同但没有print
,因为新版本有明确的print
。
我使用了s///
模式匹配,而不是m//
替换。我将分隔符更改为|
以避免斜线反斜杠(导致牙签综合征的原因)。您几乎可以使用任何标点符号。
\S
与.
类似,但仅匹配非空白字符。模式中的.*
实际上匹配斜杠前后的整个行块,但新模式仅匹配文件的路径名。由于+
是“贪婪的”,当路径名中有多个斜杠时,第一个($1
)将获得更多字符串,与替换模式相同。
答案 2 :(得分:2)
更好的版本:
-n
) print
值
perl -wnl -e '($_)=m{---\s+(\S+)} and s|/([^/]+)$|/Test$1| and print "$_\n";'
您现在不需要awk
。并将'(revision
添加到表达式
perl -wnl -e '($_)=m{---\s+(\S+)\s+\(revision} and s|/([^/]+)$|/Test$1| and print "$_\n";'
您也不需要grep
。
但我创建了几个颠覆工具,如果你想要的是更改的文件'svn st'
更好。
svn st | perl -wnle 'm/^[CM]\s+(\S+)/and$r=rindex($1,"/")+1and print substr($1,0,$r),"Test",substr($1,$r+1),"\n"'
这次我选择了rindex
+ substr
方法。现在,没有正则表达式回溯。