堅牢なルート構築

堅牢なルート構築

シェルスクリプト(zshなど)に複数の変数があるとします。

FOLDER_1, FOLDER_2, etc.

/たとえば、パスがある場合、これらの変数はで参照されます。/home/me/stuff/items

変数は次のとおりです。

FOLDER_1='home'
FOLDER_2='me'
FOLDER_3='stuff'

それでは、変数をリンクしてそのパスを再構築するとしましょう。 1つの可能なアプローチは、次のようにパスを構築することです。

PATH=$FOLDER_1/$FOLDER_2/$FOLDER_3/

しかし、一部の変数にはFOLDER_iスラッシュがあり、他の変数にはない場合(どの変数なのかわからない)とします。

FOLDER_1='home'
FOLDER_2='stuff/'
FOLDER_3='items'

私の質問は次のとおりですどのようにパスをしっかりと構築できますか?(例:二重スラッシュを避け、必要な場所に追加してください)。

/これを行う1つの方法は、常に変数ペアの間に追加してから、重複エントリを削除することだと思いましたが、それを機能させることはできsedません(/正しく実行しているかどうかはわかりませんsed)。

返品、私は車輪を再発明しているか。? (つまり、これを行うための組み込み関数はありますか?)

最後に変数がある場合大量にたとえばFOLDERS、ループをせずにこれを実行できますか? (または繰り返しますが、FOLDERS配列にいくつがあるかわかりません)

答え1

簡単な答えは心配を止め、マルチスラッシュが大好きです。複数のスラッシュは単一のスラッシュと同じ効果を持ちます。(次から始まるパスは//いくつかのシステムでは異なる意味を持ちます。WindowsのUnixエミュレーション層は私が名前を付けることができる唯一の層です。)これは意図的に設計されています。複数のスラッシュについて心配することなく、ファイル名を組み合わせることができるというのが、デザイン決定の重要な部分でした。

配列要素を連結するには、zshで次のものを使用できます。j パラメータ拡張フラグ

dir=${(j:/:)FOLDERS}

これを行う間に繰り返されるスラッシュをスカッシュすることができますが、これは純粋に装飾用です。

setopt extended_glob
dir=${${(j:/:)FOLDERS}//\/\/##/\/}

$IFSkshとbashでは、最初の文字を区切り文字として使用して配列を連結できます。その後、繰り返されるスラッシュをスカッシュできます。 Bashでは、shopt -s extglob以下のコードスニペットの最後の行でkshグローバル変数を有効にする必要があります。

IFS=/
dir="${FOLDERS[*]}"
unset IFS
dir=${dir//\/+(\/)//}

答え2

printf配列で使用できます。

parts=("$FOLDER_1" "$FOLDER_2" "$FOLDER_3");
printf '/%s' "${parts[@]%/}"
# Use "printf -v path" to save it into a variable called "path" instead of printing it

演算子は%末尾の文字列(この場合)を切り捨てます/。これを適用すると、parts[@]各アレイメンバーを個別に切り捨てます。

この技術を理解するための鍵printfは次のとおりですman 1 printf。 「フォーマット文字列は、パラメータを満たすために必要なだけ頻繁に再利用されます。」

答え3

なぜsedあなたに合わないのですか?sed 's|/\+|/|g'接続した後、または接続する前に試してくださいsed 's|/||g'

答え4

bash 4${var....}デフォルトでは、パラメータ置換... offで正規表現一致を有効にする拡張ワイルドカードが導入されました。スクリプトでこれを有効にするには、シェルオプションを設定します。外部グローバル変数...

私たちが言うと$ディレクトリ==/home/me/////////stuff//items

shopt -s extglob; dir="${dir//+(\/)//}"

結果値$ディレクトリ

/home/me/stuff/items  

以下は、やるべきこととしないことのいくつかの例です。Bash拡張ワイルドカード

関連情報