9

のような場所にルートがあるソース コード ツリーがあり/home/me/workspaceます。多くのレベルの深さの多くのサブディレクトリがあります。特に、いくつかのツールを含むパスがあります。

/home/me/workspace/tools/scripts

string を渡すツリー内の任意の場所から呼び出すことができる bash 関数を作成していますtools/scripts/この関数は、現在の作業ディレクトリからパス fragment を探すまで反復し、tools/scripts見つかった場合は、見つかった絶対パスを出力します。この例で/home/me/workspaceは、印刷されます。パス フラグメントがまったく見つからない場合は、何も出力されません。

私はすでにこれを行う次のbash関数を持っています:

search_up ()
(
    while [ $PWD != "/" ]; do
        if [ -e "$1" ]; then
            pwd
            break
        fi
        cd ..
    done
)

しかし、これは少し長すぎるようです。これを bash 自体、またはおそらく単一のfindコマンド、またはその他の一般的なユーティリティで行う方法が他にあるかどうか疑問に思っています。私は特に読みやすさと簡潔さを求めています。

ツリー全体の完全な再帰検索を探しているわけではないことに注意してください。

また、私のバッシュは最新のものではないため、最新の最高のものを使用しないでください:

$ bash --version
GNU bash, version 3.00.15(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2004 Free Software Foundation, Inc.
$
4

2 に答える 2

4

記録のために、これが私が最終的に使用したものです:

while [ $PWD != "/" ]; do test -e tools/bin && { pwd; break; }; cd .. ; done

私のOPと同様ですが、最終的にサブシェルの括弧 () を完全に削除できました。これは、この行自体が別のプログラムから「シェル」コマンドを使用して呼び出されるためです。したがって、すべてを1行に詰め込みます。

おそらくより一般的な解決策として、KonsoleBoxの合理的な回答が好きだったので、それを受け入れています。

于 2013-10-10T14:41:14.210 に答える
4

これは機能するはずですが、POSIX との互換性が必要かどうか教えてください。これの利点は、検索を行うためだけにディレクトリをより高いレベルに変更する必要がなく、サブシェルを使用する必要がないことです。

#!/bin/bash

search_up() {
    local look=${PWD%/}

    while [[ -n $look ]]; do
        [[ -e $look/$1 ]] && {
            printf '%s\n' "$look"
            return
        }

        look=${look%/*}
    done

    [[ -e /$1 ]] && echo /
}

search_up "$1"

例:

bash script.sh /usr/local/bin

出力:

/
于 2013-09-25T17:37:20.360 に答える