$ PATHとよく似ていますが、必ずしも$ PATHではない、コロンで区切られたパスリストがある場合
そのリストで特定のファイル名を検索したいのですが、最初に一致するパスのみが必要です。
次のLinuxコマンドを検討しました。
which
:バイナリでのみ機能し、$ PATH変数でのみ機能しますwhereis
:特定の種類のファイルで機能し、$ PATH変数でのみ機能しますfind
:コロンで区切られたパスリストをサポートせず、複数の結果を返しますこれが私が試したいくつかのことです:
私は次の戦略でwhereis
を使おうとしました
env WHEREIS="`which whereis`" PATH="$MY_PATH_LIST" $WHEREIS "$TARGET_FILE"
そしてこれはほとんど機能します。ただし、任意のファイルタイプの結果を返すようには見えません。また、複数の結果を扱いにくい形式で返します。
which
を動作させることができます
env WHICH="`which which`" PATH="$MY_PATH_LIST" $WHICH "$MY_TARGET_FILE"
非実行可能ファイルを許可するように強制するコマンドラインオプションがあった場合。
次に、find
で問題を解決しようとしました。まず、正規表現を使用してパスリストを展開しました(コロンをスペースに置き換えます)。次に、findを呼び出すと、正しく機能します。ただし、すべてのパスを検索します。良い結果が得られたら、検索を早く停止するように指示する方法が見つからないようです。
私はこれを機能させました
find ${MY_PATH_LIST//[:]/ } -name "$MY_TARGET_FILE" | head -n 1
ただし、find
はまだ徹底的な検索を行っているため、完了するまでに長い時間がかかります。
これは、さまざまなパラメーターを使用して何度も実行されるため、より高速に実行する(最初の結果で終了する)ために必要です。
誰かが提案するより良い解決策を持っていますか?
すべてが失敗した場合、私は非bashソリューションを書くことができることに注意してください。今すぐ書く既存のツールを使用した簡単な解決策を望んでいます。
単にテストするスクリプトを使用することができます(-e
)ファイルが存在する場合、最初のファイルが見つかったときに停止します。
#!/bin/bash
[[ $# -gt 0 ]] || { echo "Usage: $0 <filename> [pathspec]" >&2 ; exit 1 ; }
if [[ $# -gt 1 ]] ; then
P="$2"
else
P="$PATH"
fi
IFS=:
for DIR in $P ; do
if [[ -e "$DIR/$1" ]] ; then
echo "$DIR/$1"
exit 0
fi
done
例:
$ ./search.sh
Usage: ./search.sh <filename> [pathspec]
$ ./search.sh ls
/Users/danielbeck/bin/ls
$ ./search.sh pwd
/bin/pwd
$ ./search.sh ls /bin
/bin/ls
$ ./search.sh ls /usr/bin:/bin
/bin/ls
Headを使用して、findコマンドの最初の結果を取得します。
find `echo colon:separated:directories | sed 's/:/ /g'` -name filename | head -n1
または関数内:
$ function findin { find `echo $1 | sed 's/:/ /g'` -name $2 | head -n1; }
$ findin this:that:other filename