2011-10-19 48 views
1

我想从/home/user1/subdir/foo_1/foo_2/.../foo_n这样的路径中使用bash脚本提取子目录名称。 subdir将永远驻留/home/user1下,因此前缀是不变的,但有可能在subdir从路径中提取子目录的名称

一些例子是子目录的变化数量:

  • /家庭/用户1/DIR1 /事/像/这样的:RESULT :DIR1

  • /家庭/用户1/DIR2 /不同的/这/时间/:结果:DIR2

  • /家庭/用户1/DIR3 /这/是/的/最后/例如:结果:DIR3

我写这个正则表达式,但它不能正常工作:

expr /home/user1/subdir/foo_1/foo_2 : '\/home\/user1\/\(.*\/\)\{1\}' 

,但它似乎给subdir/foo_1而不是subdir

谢谢!

回答

3

的问题是,匹配是在贪婪方式完成。 .*将尽可能匹配,在你的情况下,它意味着它将匹配多个斜线,当你真的希望它停止在第一个斜线。

您明确应该/home/user1/后匹配的一切,但先下一/

expr /home/user1/subdir/foo_1/foo_2 : '\/home\/user1\/\([^\/]*\)' 

,输出:

subdir 
+0

为什么'。* \ /'匹配多个斜杠?我添加了“{1}”发布该表达式。你的解决方案是有效的,但我无法理解为什么我的正则表达式失败。谢谢@Anson – ajmartin

+0

'。*'将始终匹配尽可能多的字符(贪婪匹配)。它将匹配任何和所有字符,包括斜杠。所以在字符串'subdir/foo_1/foo_2'中,'。* /'将匹配'subdir/foo_1 /'。你的'{1}'修饰符对'。*'匹配的效果没有影响。 '{n}'只是表示在前面的表达式中匹配的任何内容都应重复n次。事实上,我刚才所说的“{1}”修饰符在这里是不必要的;我编辑了我的答案并将其删除。 – Anson

2
(?<=/home/user1/)[^/]+(?=/) 

测试:

kent$ echo "/home/user1/dir1/something/like/this"|grep -oP "(?<=/home/user1/)[^/]+(?=/)" 
dir1 
+0

的先行部分是没有必要的:匹配自然终止的斜线。 –

2

外壳可以自己做,如果你可以花一个临时变量。

t=${path#/home/user1/} 
subdir=${t%/*} 
0
dir=/home/user1/subdir/foo_1/foo_2/.../foo_n 
sub=$(IFS=/; set -- $dir; echo $4) 
echo $sub # => subdir 
相关问题