Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
regexp greedness:收缩长路径_Regex_Perl_Shell_Path_Sed - Fatal编程技术网

regexp greedness:收缩长路径

regexp greedness:收缩长路径,regex,perl,shell,path,sed,Regex,Perl,Shell,Path,Sed,请看看我的心碎 我一直在用正则表达式收缩一些很长的路径,比如: /12345/123456/1234/123/12/1/1234567/13245678/123456789/1234567890 perl -pe's#[^/]{3}\K[^/]*##g' /12345/123456/1234/123/12/1/1234567/13245678/123456789/1234567890 /123/123/123/123/12/1/123/132/123/123 我想将此路径转换为以下形式: /

请看看我的心碎

我一直在用正则表达式收缩一些很长的路径,比如:

/12345/123456/1234/123/12/1/1234567/13245678/123456789/1234567890
perl -pe's#[^/]{3}\K[^/]*##g'
/12345/123456/1234/123/12/1/1234567/13245678/123456789/1234567890
/123/123/123/123/12/1/123/132/123/123
我想将此路径转换为以下形式:

/123/123/123/123/12/1/123/123/123/123
路径中的每个“目录”仅缩写为前3个字符

LONG_PATH="/12345/123456/1234/123/12/1/1234567/13245678/123456789/1234567890"
perl -pe "s#/(.{1,3})[^/]*?(/|$)#/\1\2#g" <<<$LONG_PATH
LONG_PATH=“/12345/123456/1234/123/12/1/1234567/13245678/123456789/1234567890”

perl-pe“s#/(.{1,3})[^/]*?(/|$)#/\1\2#g”匹配最多三个非斜杠字符并捕获它们。然后匹配其余部分直到下一个斜杠。替换为捕获:

"s#(/[^/]{3})[^/]*#\1#g"
这里不需要取消reediness或任何东西,因为否定字符类与
/
$
是互斥的

编辑:虽然您似乎知道这一点,但我可能应该向未来的访问者澄清,这将适用于
perl-pe…
sed-E…
,正如您在问题中使用的那样。正则表达式也可以与sed-r一起使用。
。如果您省略了
-E
-r
选项,则(与往常一样)您将需要对括号和花括号进行转义:

sed "s#\(/[^/]\{3\}\)[^/]*#\1#g" filename

另请注意,正如ikegami指出的那样,在Perl中,您应该在替换中使用
$1
,而不是
\1

您可以这样做:

/12345/123456/1234/123/12/1/1234567/13245678/123456789/1234567890
perl -pe's#[^/]{3}\K[^/]*##g'
/12345/123456/1234/123/12/1/1234567/13245678/123456789/1234567890
/123/123/123/123/12/1/123/132/123/123
找到3个非斜杠,保留(
\K
)它们,删除以下字符直到下一个斜杠

正如ikegami指出的,不需要匹配少于三个字符,在这种情况下,可以使用lookback断言来代替
\K
。好处是
\K
需要PerlV5.10,我相信环顾断言早于此

perl -pe 's#(?<=[^/]{3})[^/]*##g'

perl-pe的#(?最好的方法似乎是使用模块来拆分和重新组合路径。对
map
的中间调用会将每个路径段缩减为其前三个字符。此程序演示

use strict;
use warnings;

use File::Spec;

my $path = '/12345/123456/1234/123/12/1/1234567/13245678/123456789/1234567890';

my $newpath = File::Spec->catdir(map substr($_, 0, 3), File::Spec->splitdir($path));

print $newpath;
输出

/123/123/123/123/12/1/123/132/123/123

我用
GNU sed版本4.2.1
@shiplu.mokadd.im得到了这个
sed:-e表达式#1,char 24:s命令的RHS
上的无效引用\1;同样的版本对我来说很好:
sed-e“s#(/[^/]{1,3})[^/]*\1#g”文件名
,通过添加
-r
你可以告诉sed使用扩展的regexp。(如果没有-r,则需要跳出()对于\.要使用ERE,我认为OSX的sed是
-E
,反之则是
-r
。否则,请跳出括号。@shiplu.mokadd.im我的答案只是提供了可在perl或sed中使用的正则表达式,这就是为什么我没有在答案中包含任何命令。
-E
只是从OPs问题中提取出来的(摘自他的一个例子),我想我的正则表达式可以与所有的操作一起工作。正则表达式对我来说仍然有暗角,这很好。感谢这个有趣的例子。@ikegami有趣的编辑。。如果使用了它,
\K
可以交换为lookback,同时稍微减少perl版本依赖性。是否要缩短这两个目录和文件?如果只使用前者:
sed-r':a;s |(/[^/]{3})[^/]+/[124;\ 1/| g;ta'文件