パスの正しい終了を解決するにはどうすればよいでしょうか?

パスの正しい終了を解決するにはどうすればよいでしょうか?

このパスを保持するシェル変数を取得しました

/usr/share/man/man1/bitmap.1

bitmap.1 という名前のファイルが存在する可能性もありますが、bitmap.1.z、bitmap.1.gz、bitmap.1.Z という名前である可能性もあります。

ここで、実際のファイルを関数に渡し、同時に正しいファイルを解決したいと思います。

function process {
    # do something
}

path="/usr/share/man/man1/bitmap.1"

process ${path}.(z|Z|gz) # here the shell shall resolve the real filename

これをエレガントに行う方法はありますか、それとも bitmap.1、bitmap.1.z などが存在するかどうかをテストしてから、そのファイルを関数に渡す必要がありますか?


言い忘れましたが、私は Bourne-Shell に制限されているので、Brace Expansion は手元にありません -,-。

答え1

Bourne Shellでもグロブは可能です

for f in ${given-path}*; do
process $f
done

シェル スクリプトをできる限り Bourne シェル構文に限定して作成すると、移植性が最大限に高まります。多くの場合、速度も向上します。

答え2

可能な拡張子のリストがわかっている場合は、次の操作を実行できます。

process ${path}{,.Z,.Z,.gz}

答え3

Christian の言うことは正しいと思います。パスの少なくとも一部がわかっている場合は、Bash の組み込みグロブを使用すると、パターンに一致するファイルがすべて表示されます。

たとえば、私は .profile に、gzip 形式およびプレーンテキスト形式のログ ファイルを cat するために頻繁に使用する関数を用意しています。

function mscat {
  is_gzip="\.gz$"

  for file in $@; do
    if [[ "$file" =~ $is_gzip ]]; then
      zcat $file
    else
      cat $file
    fi
  done
}

これを次のように呼びます:

mscat /var/log/ncftpd/sess.2010*

グロブによって複数の結果が生成される可能性があるため、'process' 関数は複数の引数に対して動作できる必要があります。私の例では、$@ 内の各引数を反復処理することで、これをどのように実行しているかがわかります。

答え4

ファイルが1つしかない場合は、bash globbingを使用できます。process ${path}*

関連情報