2011-10-19 9 views
1

/home/user1/subdir/foo_1/foo_2/.../foo_nのようなパスからbashスクリプトを使用してサブディレクトリ名を抽出したいとします。結果:/ /このようなパスからサブディレクトリの名前を抽出する

  • /ホーム/ user1の/ DIR1 /何か: subdirは常にプレフィックスが不変であるが、subdir

    いくつかの例を下のサブディレクトリの数は変えることができるので、/home/user1の下に存在します:DIR1

  • /ホーム/ user1の/ DIR2 /異なる/この/時間/:RESULT:dir2の

  • /ホーム/ user1の/ DIR3 /本/である///最後の例:結果:DIR3

私はこの正規表現を書いたが、それは正しく動作しません:

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

が、subdir/foo_1代わりのsubdirを与えているようです。

ありがとうございます!

答えて

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

問題は、マッチングが貪欲な方法で行われることです。 .*は可能な限り一致します。実際には最初のスラッシュで停止したいときは、複数のスラッシュと一致することを意味します。

あなたは、具体的/home/user1/後にすべてを一致させるべきであるが、出力の次の/

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

の前に:あなたは、一時的な変数を過ごすことができるかどう

subdir 
+0

'。* \ /'は複数のスラッシュにマッチするのはなぜですか?私は '{1}'を追加しました。あなたのソリューションは動作しますが、なぜ私の正規表現が失敗しているかについて私の頭を浮かべることはできません。 Thanks @Anson – ajmartin

+0

'。*'は常に可能な限り多くの文字と一致します(欲張りの一致)。スラッシュを含むすべての文字に一致します。だから、文字列 'subdir/foo_1/foo_2'では、'。*/'は' subdir/foo_1/'にマッチします。あなたの '{1}'修飾子は '。*'がどのくらい一致するかには影響しません。 '{n}'は直前の式でマッチしたものがn回繰り返されることを意味します。実際に、 '{1}'修飾子は、私が今述べた理由でここでは不要です。私は私の答えを編集し、それを削除しました。 – Anson

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

試験:

+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 
関連する問題