2017-10-18 7 views
2

外部コマンドを使用しないように、Bashにdirname関数を書き込もうとしています。Bashの文字列からパターンのすべてのマッチを取り除くか置き換えるか?

function dirname() { 
    local path=$1 
    [[ $path =~ ^[^/]+$ ]] && dir=. || {    # if path has no slashes, set dir to . 
    [[ $path =~ ^/+$ ]] && dir=/ || {    # if path has only slashes, set dir to/
     local IFS=/ dir_a i 
     read -ra dir_a <<< "$path"     # read the components of path into an array 
     dir="${dir_a[0]}" 
     for ((i=1; i < ${#dir_a[@]}; i++)); do  # strip out any repeating slashes 
     [[ ${dir_a[i]} ]] && dir="$dir/${dir_a[i]}" # append unless it is an empty element 
     done 
    } 
    } 

    [[ $dir ]] && printf '%s\n' "$dir"    # print only if not empty 
} 

パスから任意の繰り返し/を除去するために、私は、アレイ・ロジックを使用しなければなりませんでした。 Bash Parameter Expansionでこれを行う簡単な方法はありますか?私は試しましたが、私は正しいことをしていないようです。

基本的に、複数の連続したスラッシュのすべてをそれぞれ1つのスラッシュに置き換えたいとします。

+0

'echo" $ {path%\/*} "'? – Cyrus

+0

それは最後の '/'のみを削除します。例:pathが 'a // b // c /// d'ならば、' a // b // c // 'となります。 – codeforester

+0

ちょうど好奇心から、 'a // b // c /// d'のようなパスはどこにありますか?私が近くで実行したのは、 'drive:\\ a \\ b \\ c \\ file.ext'を含むWindowsパスコンポーネントをPOSIXドライブに変換することだけです:/a/b/c/file.ext '。 'a // b // c /// d'のようなパスをどこで作成できますか?ウインドウズ?あるいは、これは単なる一般的なストリップの複数の '' // ''*エクササイズですか? –

答えて

4

extglobが上にある場合:

printf '%s\n' "${path//\/+(\/)/\/}" 

これはグローバル置換を行うために${var//pattern/replacement}の構文を使用します。

shopt -s extglob 

あなたはこれを行うことができます。実際/+(/)ある

/はデリミタであるため、エスケープスラッシュで)パターンが\/+(\/)ある、(+(/)「は一つ以上のスラッシュ」を意味します)。

関連する問題