这个问题纯粹是化妆的:
我想删除给定字符串的最后一个“/”之后的所有文本。所以如果输入是
mkdir -p $DEST/Users/Peter/Dropbox/Public/Vacation/P1000891.jpg
输出应为
mkdir -p $DEST/Users/Peter/Dropbox/Public/Vacation/
(确切地说,输出中是否包含最后一个“/”并不重要。)
我找到了各种方法,例如:
my @templist = split "/", 'mkdir -p $DEST/Users/Peter/Dropbox/Public/Vacation/P1000891.jpg';
print join "/", splice(@templist, 0, -1);
或者:
my ($a) = 'mkdir -p $DEST/Users/Peter/Dropbox/Public/Vacation/P1000891.jpg' =~ /(.*\/)+(?:[^\/]+)/;
print $a;
但是我认为这应该只使用正则表达式来实现,也许只能使用搜索&更换?也许有先见之明?
答案 0 :(得分:7)
只需删除字符串末尾的所有非斜杠字符:
s|[^/]+$||;
顺便说一下,前瞻是一种检查模式中某个位置发生某种事情的方法,而不是实际向前移动匹配位置。简单的匹配任务很少需要它,但是那些不太了解它的人似乎过度使用它。
答案 1 :(得分:2)
use File::Basename qw( dirname );
dirname($path)
答案 2 :(得分:1)
s/(.*\/).*$/$1/g
测试如下:
> echo "a/b/c/d/e/f/remove this"|perl -pe 's/(.*\/).*$/$1/g'
a/b/c/d/e/f/
答案 3 :(得分:1)
您提到正则表达式和 perl 作为标记。问题(正如你所发现的)是正则表达式是贪婪的。有两种方法可以解决这个问题:
grep
和sed
中,您拥有一组有限的正则表达式。你所做的就是利用你不想要删除任何斜线的事实。因此:
$directory =~ s(/[^/]+$)();
(我使用括号作为正则表达式分隔符,所以我没有山丘和山谷影响如下:s/\/[^\/]//
)。这是说从最后匹配所有现在正斜杠字符前面的正斜杠,然后什么都不替换。
但是,它看起来只是想要从目录中删除文件名。 Perl有一种内置的处理方式。它被称为dirname
函数:
use File::Basename;
[...];
print "mkdir -p " . dirname $directory . "\n";
这使得你非常清楚地知道自己在做什么。此外,它将适用于替代操作系统,这些操作系统不使用标准正斜杠进行目录分离(咳嗽 Windows!咳嗽)
答案 4 :(得分:0)
以前的解决方案比我的好,但我想与您分享:
perl -e 'my $str = "mkdir -p \$DEST/Users/Peter/Dropbox/Public/Vacation/P1000891.jpg"; my ($res)=$str=~m|(.+/)|; print $res;'
打印:
mkdir -p $ DEST / Users / Peter / Dropbox / Public / Vacation /
所以,m|(.+/)|
贪婪地吞噬了一切,直到最后一次" /"。然后我们说应该有一个" /"在我们关注的部分。