regexp贪婪:缩小长路

sar*_*ana 2 regex shell perl sed path

请看看我的思想破坏者.

我坚持用正则表达式缩小了一些长路径,就像这样:

/12345/123456/1234/123/12/1/1234567/13245678/123456789/1234567890
Run Code Online (Sandbox Code Playgroud)

我想将此路径转换为以下形式:

/123/123/123/123/12/1/123/123/123/123
Run Code Online (Sandbox Code Playgroud)

路径中的每个"目录"缩写为仅3个第一个字符

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

/ 123 /123分之123456/12分之123//132分之1234567/123分之123456789

sed -E "s#/(.{1,3})[^/]*?(/|$)#/\1\2#g" <<<$LONG_PATH
Run Code Online (Sandbox Code Playgroud)

/ 123 /123分之123456/12分之123//132分之1234567/123分之123456789

我也试过了:

perl -pe "s,/(.)(.)?(.)?[^/]*+,/\1\2\3,g" <<<$LONG_PATH
/123/123/123/123/12//123/132/123/123
Run Code Online (Sandbox Code Playgroud)

还有很多,没有"运气" - 我仍然不知道.

请指出一个成功的正确方法.

Mar*_*der 7

最多匹配三个非斜杠字符并捕获它们.然后匹配其余的直到下一个斜线.替换为捕获:

"s#(/[^/]{3})[^/]*#\1#g"
Run Code Online (Sandbox Code Playgroud)

这里不需要不合情理或任何东西,因为否定的字符类与/or 相互排斥$.

编辑:尽管你似乎知道这一点也许我应该澄清未来的访客,这将与任何工作perl -pe...sed -E...因为你已经在你的问题中使用它.正则表达式也可以按原样使用sed -r....如果你省略了-E-r选项,那么(像往常一样)你将需要转义圆括号和大括号:

sed "s#\(/[^/]\{3\}\)[^/]*#\1#g" filename
Run Code Online (Sandbox Code Playgroud)

另请注意,ikegami指出,在Perl中你应该使用$1替换而不是\1.