$ PATHでワイルドカード文字と一致するコマンドを実行します。

$ PATHでワイルドカード文字と一致するコマンドを実行します。

$PATH現在、このワイルドカードlibreoffice?.?(たとえばlibreoffice4.0libreoffice4.3など)に一致するコマンドを見つけて実行したいと思います。

編集:一致するものが複数見つかった場合は、ランダムに1つを選択できます。

私はPOSIX互換ソリューションを好む。

ベストアンサー1

コロンで区切られた値IFSに設定します。コマンドが存在することがわかっていて、コマンドの戻りコードに興味のない操作や専攻(FreeBSD、OSX、GNUなど)がある場合は、次の行を使用できます。:PATHfind-quit-maxdepth

pattern='libreoffice?.?'
IFS=:; find $PATH -maxdepth 1 -type f -name "$pattern" -exec {} \; -quit; unset IFS

これは、コマンドが見つかったかどうかを報告する簡単な方法を提供しません。さらに強力になるには、値にワイルドカードが含まれている場合はワイルドカードをオフにしますPATH。あるいは、PATH現在のディレクトリを表す空のコンポーネントがあるかもしれません(しかし私の提案は.それを使うことです)。以下のコードはこれらすべての複雑さを解決します。

pattern='libreoffice?.?'
case $PATH in
  :*) directories=.$PATH;;
  *::*) directories=${PATH%%::*}:.:${PATH#*::};;
  *:) directories=$PATH.;;
  *) directories=$PATH;;
esac
set -f; IFS=:
cmd=
for d in $directories; do
  set +f
  for x in "$d"/$pattern; do
    if [ -x "$x" ] && ! [ -d "$x" ]; then
      cmd=$x
      break
    fi
  done
  if [ -n "$cmd" ]; then break; fi
done
set +f; unset IFS
if [ -z "$cmd" ]; then
  echo 1>&2 "$pattern: not found in PATH"
  exit 127
else
  exec "$cmd"
fi

通常のsh、bash、kshなどの代わりにzshを使用している場合は、強力なソリューションを見つけるのがはるかに簡単です。

pattern='libreoffice?.?'
matches=($^path/$~pattern(N.*[1]))
if ((!#matches)); then
  $matches[1]
else
  echo 1>&2 "$pattern: not found in PATH"
  exit 127
fi

おすすめ記事