2011-10-19 104 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 
相關問題