2016-07-11 14 views
3

私はパラメータとしてディレクトリを取り込むBashスクリプトを用意しています。処理の後、そのディレクトリのファイルに基づいて出力を行います。Bashで省略可能な/(ディレクトリ区切り文字)を削除する

コマンドはdir

dir/foo 
dir/bob 
dir/haha 
dir/bar 
dir/sub-dir 
dir/sub-dir/joe 

> myscript ~/files/stuff/dir 

内部に次のような構造を持つディレクトリには、いくつかの処理の後で、次のようになり、私はこの

foo 
bar 
sub-dir/joe 
のようなものであることを出力したいのですが

渡されたパスを削除するコードは次のとおりです。

shopt -s extglob 

for file in $files ; do 
    filename=${file#${1}?(/)} 

これは私に次のようになりますが、何らかの理由でオプションの/が処理されていません。このように、私の出力は次のようになります。

/foo 
/bar 
/sub-dir/joe 

ユーザーが、私はそれはまだ仕事をしたいコマンド

> myscript ~/files/stuff/dir/ 

を実行している場合ので、私はそれはオプション作っている理由があります。そして、そのコマンドの後ろにスラッシュをつけてコマンドを実行すると、望みどおりに出力されます。

私の?(/)はなぜ機能しないのですか?私が読んだことすべてに基づいて、それは正しい構文でなければなりません、私はいくつかの他のバリエーションも試してみました。

ありがとうございました。

+2

'# 'は可能な限り短いものと一致するので、オプションの部分は決して含まれません。可能な限り一致させるために '##'を使うことができました –

+0

@thatotherguy、それはうまくいきました!ああ!ドキュメンテーションでそれについて何も見ていない。それを答えにしたいのであれば、私はそれを受け入れるでしょう。 – David

答えて

2

はここで、 "パラメータ展開" の下man bashからのドキュメントです:

${parameter#word} 
    ${parameter##word} 
      Remove matching prefix pattern. The word is 
      expanded to produce a pattern just as in pathname 
      expansion. If the pattern matches the beginning of 
      the value of parameter, then the result of the 
      expansion is the expanded value of parameter with 
      the shortest matching pattern (the ``#'' case) or 
      the longest matching pattern (the ``##'' case) 
      deleted. 

#は最短マッチを削除しようとしているので、それは任意の末尾が含まれることはありませんオプションパーツ。

あなただけの代わりに##を使用することができます。

filename=${file##${1}?(/)} 

をスクリプトが行い、それがどのように動作するか、あなたはまた、単にディレクトリにcdにそれを書き換えることができます内容に応じて常に.

に相対パスで動作するように
3

filesを、スペースを含む可能性のある非標準のファイル名の可能性のある回避策に変更することをお勧めしました。

files=("dir/A/B" "dir/B" "dir/C") 
for filename in "${files[@]}" 
do 
    echo ${filename##dir/} #replace dir/ with your param. 
done 

出力

A/B 
B 
C 
4

that other guy's helpful answerあなたの当面の問題を解決し、何も価値が二つのものがあります。

  • 引用符で囲まれていない文字列変数(for file in $files)を含むファイル名を列挙すると、sjsam's helpful answerが指摘されているので注意が必要です。スペースに埋め込まれたファイル名とグロブのようなファイル名で壊れます。前述のように、の配列にファイル名を格納することは堅牢な選択です。

  • がグローバルシェルオプションshopt -s extglob変更する厳格な必要はありません:

# Sample values: 
file='dir/sub-dir/joe' 
set -- 'dir/' # set $1; value 'dir' would have the same effect. 

filename=${file#${1%/}} # -> '/sub-dir/joe' 

内部パラメータ:ネストされたすることができ、パラメータ展開は、そのシェルのオプションを変更せずに動作します、次の拡張、${1%/}は、末尾の(%/$1(存在する場合)から削除します。

関連する問題