完成这个 Perl regex 一行的最佳方式

发布于 2024-10-02 04:23:12 字数 662 浏览 2 评论 0原文

我正在尝试使用 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/one-liner 技能 那么我如何修改 perl one-liner 来仅提取文件路径呢?

 svn diff | grep '(revision' | perl -wpl -e 's/(.*)\/(.*)$/$1\/Test$2/' | awk '{print $2}' | xargs run_test.sh

I'm trying to use a Perl one-liner to munge some output from grepping svn diff, so I can automatically test the files. We have a run_test.sh script that can take multiple PHP files prepended with 'Test" as its arguments.

So far I have the following which successfully prepends 'Test' to the file names

[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)

Now I'd just like to grab the file/path to pass it to our run_test.sh. I can finish it off with awk as below, but am trying to improve my Perl/one-liner skills. So how do I revise the perl one-liner to additionally extract only the file path?

 svn diff | grep '(revision' | perl -wpl -e 's/(.*)\/(.*)$/$1\/Test$2/' | awk '{print $2}' | xargs run_test.sh

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我是男神闪亮亮 2024-10-09 04:23:12

您只需要文件名,因此 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。)

You're just wanting the file names, so svn st is what you want. Instead of getting large quantities of noise which could potentially contain (revision in it, and the main lines you want, you'll get it like this: M commerce/LCart.php. Then you can just chop off \S* (any number of non-whitespace characters) followed by \s* (any number of whitespace characters), and take what's left. You could do the \S*\s* differently, but that's the simplest way to get all cases.

svn st | perl -wpl -e 's|\S*\s*(.*)/(.*)$|$1/Test$2|'

(Switched it after posting from using s/// to s||| so the / doesn't need to be escaped; good idea, Axeman.)

城歌 2024-10-09 04:23:12

您可以相当轻松地摆脱 grepawk

svn diff | perl -wnl -e '/\(revision/ or next; m|(\S+)/(\S+)|; print "$1/Test$2";'

我将 -p 更改为 -n。 -p 表示 while (<>) { <您的代码>;打印 $_; } 和 -n 是相同的,但没有 print,因为新版本有一个显式的 print

我没有使用 s/// 替换,而是使用了 m// 模式匹配。我将分隔符更改为 | 以避免反斜杠斜杠(倾斜牙签综合症的原因)。您几乎可以使用任何您想要的标点符号。

\S. 类似,但仅匹配非空白字符。模式中的 .* 实际上匹配斜杠之前和之后的行的整个块,但新模式仅匹配文件的路径名。由于 + 是“贪婪的”,因此当路径名中有多个斜杠时,第一个 ($1) 将获得更多字符串,与替换模式相同。

You can get rid of the grep and the awk fairly easily.

svn diff | perl -wnl -e '/\(revision/ or next; m|(\S+)/(\S+)|; print "$1/Test$2";'

I changed the -p to -n. -p means while (<>) { <your code>; print $_; }, and -n is the same but without the print, since the new version has an explicit print instead.

Rather than an s/// substitution, I used an m// pattern match. I changed the delimiter to | to avoid backslashing the slash (a cause of Leaning Toothpick Syndrome). You can use almost any punctuation character you want.

\S is similar to . but matches only non-whitespace characters. Your .*s in the pattern were actually matching the entire chunks of the line before and after the slash, but the new pattern only matches the pathname of the file. Since the + is "greedy", the first one ($1) will get more string when there are multiple slashes in the pathname, the same as with your substitution pattern.

日记撕了你也走了 2024-10-09 04:23:12

更好的版本:

  • 无默认打印 (-n)
  • 首先提取子字符串
  • Subst 在该
  • print

    perl -wnl -e '($_)=m{---\s+(\S+)} 和 s|/([^/]+)$|/Test$1|并打印“$_\n”;'
    

您现在不需要awk。并且在表达式中添加 '(revision

perl -wnl -e '($_)=m{---\s+(\S+)\s+\(revision} and s|/([^/]+)$|/Test$1| and print "$_\n";'

您也不需要 grep

但是我创建了几个 subversion 工具,如果您想要的只是更改的文件< code>'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 方法,现在没有正则表达式回溯。 。

Better version:

  • No default print ( -n)
  • Extract substring first
  • Subst on that
  • print value

    perl -wnl -e '($_)=m{---\s+(\S+)} and s|/([^/]+)$|/Test$1| and print "$_\n";'
    

You don't need awk now. And adding '(revision to the expression,

perl -wnl -e '($_)=m{---\s+(\S+)\s+\(revision} and s|/([^/]+)$|/Test$1| and print "$_\n";'

you don't need grep either.

But I have several subversion tools I created, and if all you want are the changed files 'svn st' is better.

svn st | perl -wnle 'm/^[CM]\s+(\S+)/and$r=rindex($1,"/")+1and print substr($1,0,$r),"Test",substr($1,$r+1),"\n"'

This time I chose a rindex + substr method. Now, there's no regex backtracking.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文