2011-04-28 14 views
1

私は、次のコードは、文字列の最後のディレクトリを削除し各1バッシュ変数の展開

dirs="/home /home/a /home/b /home/a/b/c" 

の後にスペースを持つディレクトリで構成された文字列を持っています。

dirs=${dirs% * } 

これは1つのディレクトリのみが文字列であるときを除いて、すべてのケースで動作し、それはそれの前にスペースを持っていないので、それはそれは削除されません。
これを修正する簡単な方法があると確信していますが、私は立ち往生しています。
可能であれば、if文を使用しない1行の方法が望ましいです。

おかげ

答えて

3
$ dirs="/home /home/a /home/b /home/a/b/c" 
$ dirsa=($dirs) 
$ echo "${dirsa[@]::$((${#dirsa[@]}-1))}" 
/home /home/a /home/b 
$ dirs="${dirsa[@]::$((${#dirsa[@]}-1))}" 
$ echo "$dirs" 
/home /home/a /home/b 
$ dirs="/home" 
$ dirsa=($dirs) 
$ dirs="${dirsa[@]::$((${#dirsa[@]}-1))}" 
$ echo "$dirs" 

または、あなたが知っている、ちょうど配列として全体の時間をそれを保ちます。

$ dirs=(/home /home/a /home/b /home/a/b/c) 
$ dirs=("${dirs[@]::$((${#dirs[@]}-1))}") 
$ echo "${dirs[@]}" 
/home /home/a /home/b 
+0

クールで、何が起こっているのかわかりにくいです。私が正しいかどうか教えてください。 – slicedtoad

+0

...私のコメントの残りの部分に何が起こったのか分かりません。とにかく、#dirs [@]は文字列を単語の配列に変換し、-1はそれを1文字ずつ短縮します。 – slicedtoad

+0

'$ {#dirs [@]}'は配列の長さを返します。 '$ {dirs [@] ::}'は配列をスライスします。したがって、最後の要素を配列からスライスします。 –

0

私は誰かがより良いものを提供します確信しているが、

case "$dirs" in (*" "*) dirs="${dirs% *}" ;; (*) dirs="" ;; esac 
0
$ dirs="/home /home/a /home/b /home/a/b/c" 
$ [[ $dirs =~ '(.*) (.[^ ]*)$' ]] 
$ echo ${BASH_REMATCH[1]} 
/home /home/a /home/b 
$ dirs="/home" 
[[ $dirs =~ '(.*) (.[^ ]*)$' ]] 
$ echo ${BASH_REMATCH[1]} 
1

まず、端から任意の非空白文字を削除します。末尾の空白を削除します。

dirs="/home /home/a /home/b /home/a/b/c" 
dirs="${dirs%"${dirs##*[[:space:]]}"}" && dirs="${dirs%"${dirs##*[![:space:]]}"}" 
echo "$dirs" 
+0

うわー、それは私の脳を傷つけています。私は時間が足りませんが、後でそれを理解し、イグナシオを使用します。ありがとう – slicedtoad

関連する問題