web-dev-qa-db-ja.com

「locate」を使用して実行可能ファイルのみをどのように見つけるのですか?

locate gtagsは、gtagsという名前のすべてのファイルを検索します。

実行可能ファイルのみが必要な場合はどうすればよいですか?

7
Jichao

簡単ではありません。使用できます

locate bash | while IFS= read -r line; do [[ -x "$line" ]] && echo $line; done

名前にbashが含まれるすべての実行可能ファイルを検索します。チェックする必要があるのは数個のファイルだけなので、ファイルシステム全体でfindを使用するよりも高速です。


  • locate bashは常に何をするか(すべての一致をリストします)
  • |(パイプ)は最初のコマンド(locate)から出力を受け取り、2番目のコマンド(行の残りの部分)に送信します
  • while ...; do ... doneループは(locateから)パイプから受け取ったすべての行を反復します
  • read -r lineは1行の入力を読み取り、それをline(この場合はパス/ファイル名)という変数に格納します。
  • [[ -x "$line" ]]は、ファイルが$lineは実行可能です
  • もしそうなら、&& echo $lineパーツが画面に印刷します
6
nohillside

最速かつ最も安価なソリューション:

locate -b '\gtags' | xargs -ri find {} -Prune -type f -executable

xargsのマニュアルページによると、上記の構文はlocateで見つかったすべてのファイル名をfindの単一の実行に渡し、指定したファイルのみを検査します。

このソリューションは、次の理由により、以前に提供されたものよりも優れています。

  • ルートディレクトリで始まるシステム上のすべてのファイルを検索するためにfindを使用するのは短いコマンドですが、実行に非常に長い時間がかかる場合があります。
  • シェルのwhileループを使用して各ファイル名をチェックすると、一度に1つのファイルをチェックするため、時間がかかる場合があります。

他の人が以前の回答で与えられたパラメーターの詳細な説明を求めてきたので、詳細は次のとおりです。

  • locate(参照: locate-ファイルの検索
    • -b:パス名のベースファイル名のみを指定したパターンと照合します。パス名内のディレクトリの名前は考慮しません。
    • \:バックスラッシュはグロブ文字であるため、locategtags*gtags*であるかのように処理することを防止します。つまり、「gtags」という正確な名前を持ち、前後に他の文字がないファイルを探します。
  • xargs(参照: xargsオプション-ファイルの検索
    • -r:標準入力が完全に空の場合は、コマンドを実行しないでください。
    • -i:次のコマンドの{}を、標準入力から読み取ったファイル名のリストに置き換えます。
  • find(参照: find Primary Index-Finding Files
    • {}xargsは、標準入力でlocateから受け取るすべてのファイルの名前でこれを置き換えます。 findは、これらのファイルすべてを検索して、次の式との一致を探します。それらのいずれかがディレクトリである場合は、それらの内容も調べます。
    • -Prune:評価されるファイル名がディレクトリに属している場合、その内容を検索しないでください。
    • -type f:デバイスや名前付きパイプなどの特別なファイルではなく、「通常の」ファイルに属するファイル名のみを出力に含めます。
    • -executable:実行可能ファイルのファイル名のみを出力に含めます。つまり、ファイルの内容に関係なく、1つ以上の実行可能モードビットが設定されているものです。

つまり、locateは、一致するファイルの名前を標準出力に出力します。これは、|を使用してxargsの標準入力にパイプ処理されます。 xargsは、標準入力からファイル名を読み取り、それらを単一の文字列のスペース区切りリストに結合します。文字列が空でない場合、xargsは、実行する前にfindコマンドの{}を文字列に置き換えます。

4
L S

短い答え、GNUを使用:

find / -type f -executable -name '*gtags*'
2
A.B.