存在しない可能性があるディレクトリセットを探す

存在しない可能性があるディレクトリセットを探す

生成された「開始点」セットから find を呼び出す必要がありますが、一部のパスが無効である可能性があります。

paths() {
    #
    # mock version of the generator
    #
    echo /bin
    echo kjsdfhk
    echo /etc
}

find $(paths) -type f name foo.sh

私の問題は、パスが有効であるかどうかわからず、そうでない場合は静かに無視したいということです。私にとって最も簡単なことは今です。

paths \
  | while read path;
    do
        test -e "$path" || continue
        find "$path" -type f -name foo.sh
    done

しかし、これは高価です。探すすべての有効なパスに対して、コード全体をループ内で呼び出すことができるので、より効率的な方法を見つけたいと思います。

シンプルで非常にUnixのソリューションは次のとおりです。探すSTDINで「スタートポイント」を読んでください。

paths \
  | while read path;
    do
        test -e "$path" || continue
    done \
  | find - -type f -name foo.sh

それを除いて...探すこれはサポートされていません! :)

どんなアイデアがありますか?

パスはユーザーが提供するため、スペース(およびその他の興味深い事項)を考慮する必要があります。また、POSIXを目指していますが、/bin/sh犠牲になる可能性があります。 (ああ、STDERR全体を沈めることも/dev/nullオプションではありません...)

修正する:申し訳ありません。 bashだけが利用できることを言及するのを忘れていました。 POSIXのコメントのため、より混乱する可能性があります。実際、コードはBashスクリプトでソースコードの断片を探しており、そのほとんどは現在次の場所にあります。シェン今後のバージョンでは、いくつかの屈辱感を取り除くことができます。したがって、より多くのbashismを追加することを避けることができれば素晴らしいです。しかし、@stephaneの答え(今投票してください!)のように、どんなにエレガントであっても、「zshisms」を余裕がありません。

ベストアンサー1

zsh配列に次のパスがある場合:

files=($(paths))

paths(これにより、出力は空白、タブ改行、またはヌルに分割されます)または:

files=(${(f)"$(paths)"})

行を分割するには、次のようにします。

find $^files(N) -type f -name foo.sh

またはディレクトリに制限したい場合:

find $^files(/N) -type f -name foo.sh

これで、これらのファイルがない場合は、次のように実行できます。

find -type f -name foo.sh

一部のfind実装(GNUなど)では、これは現在のディレクトリから検索することを意味します。これを防ぐには、次のようにします。

dirs=($^files(/N))
(($#dirs)) && find $dirs -type f -name foo.sh

または:

setopt cshnullglob
find $^files(/) -type f -name foo.sh

今はzshもう必要ありませんfind。簡単に次のことができます。

files=($^files/**/foo.sh(.N))

!これにより、ファイルが類似またはブロック-nameされている場合でも操作が容易になります。find

ただし、ファイルがディレクトリへのシンボリックリンクである場合(findここではファイルを見つけることはありませんが、実際に望むものかもしれません)、zsh状況は異なります。

おすすめ記事