ターゲット検索からディレクトリを除外

ターゲット検索からディレクトリを除外

検索はlocateファイルシステム内のパスを探します。
多くの場合、ファイルやディレクトリにのみ興味があることを先験的に知っています。
「検索」検索は通常多くの結果を返します。結果に1つのタイプしか含めないと、出力を減らすのに役立ちます。

しかし、ファイルやディレクトリを無視することについてのより興味深い主張があります。なぜなら、結果パスのリストは理論上だけでなく曖昧になる可能性があるからです。

次の例は実際のケースであり、まれではありません。

$ locate --regex --basename "xfce4-keyboard-overlay$"
/usr/local/bin/xfce4-keyboard-overlay
/usr/local/share/xfce4-keyboard-overlay

さて、何かが見つかりました!しかし…ファイルですか、それともディレクトリですか?

$ file /usr/local/bin/xfce4-keyboard-overlay 
/usr/local/bin/xfce4-keyboard-overlay:   bash script

それではここにファイルがあります...

$ file /usr/local/share/xfce4-keyboard-overlay
/usr/local/share/xfce4-keyboard-overlay: directory

2番目はそうではありません。

これらのあいまいさは長いパスのリストを読みにくくするのでlocate

そんなことがありますか?ディレクトリフィルタリングはターゲティングとは別のものですか?

少なくともスクリプトを使用して、すべてのファイル名を繰り返し確認することができます。これは遅くなる可能性があります。

答え1

そしてzsh

print -rC1 ${(0)^"$(locate -0 ...)"}(N.)

(0)は、パラメータ拡張フラグでNUL文字で区切られており(使用されているとおりlocate -0)の略語です(ps:\0:)

の場合は、配列の末尾に追加する^代わりに各要素に追加します。(N.)

(N.).通常のファイルとのみ一致し、N一致しない場合(存在しない、通常のファイルでない、または確認できない場合)、要素を削除するglob修飾子。通常のファイルではなく、ディレクトリ以外の項目を一致させる^/ために置換を使用することもできます。.または、-.ファイルの種類を決定します。シンボリックリンク解決後(一致する一般ファイルへのシンボリックリンクを含みます)。

print -rC1各パラメータの印刷生のolumnに(印刷する項目がなく、何も出力せずに空白行を印刷する点を除けば、1行に1つずつ書き込むのと1 C同じ)-lprint -C1print -l

zshすべてのグローバル修飾子を使用できますが、注文するここではファイルごとにglobを拡張するので、何の効果もありません。したがって、ソートするファイルごとに1つしかありません。

どのファイルが実行可能ファイル/ディレクトリ/シンボルリンク/ソケットであるかをよりよく識別するには...結果ファイルをパラメータとして渡し、いくつかのls -F...*/@=サフィックスを追加することもできます。

これは、GNUツールやBourneに似たシェルを想定しています。

elocate() {
  locate -0e "$@" |
    sort -z |
    xargs -r0 ls --quoting-style=shell --color=always -Fd1U |
    less -FIXR
}

あいまいさを避けるために、ファイル名をシェルスタイルで引用し、タイプを表示するためにサフィックスを追加してカラーバージョンとページバージョンの両方を提供する関数を定義elocateします。locate

答え2

これは他の答えほどエレガントではありませんが、おそらくそれほど効率的ではありません。

locate --regex --basename "xfce4-keyboard-overlay$" | 
        while IFS= read -r f; do [ -f "$f" ] && printf "%s\n" "$f"; done

(読みやすくするために2行に分割します。)上記は、スペースを含む名前を処理します。IFS=名前を扱う必要があるようです。続くもちろん、スペースを使用すると-rバックスラッシュも処理できます。

locate「何かをパイプで接続しよう」アプローチは、改行文字を含むパス名があると失敗する可能性があります。


詳しくは、* nixシステムで、またはを入力またはIFS読んでください。sh(1)bash(1)man shman bashここここここ、そして/またはここ)。それでは読んでください。IFSについて学ぶ そしてBash:IFSを使用して1行ずつ読み込むStack Exchangeで(5票以上投票した回答に従ってください)、まだ十分でない場合は確認してください。Greg WikiのIFS そしてBash Hackers WikiのIFS検索結果(スタック交換ではない)

答え3

xargs-L 1または引数を指定すると、各行に対してコマンドが繰り返されます-i

ねえ

$ locate --regex --basename "xfce4-keyboard-overlay$" | xargs -i bash -c '(test -d "{}" && echo "{}")'

もちろん、各ファイルごとに新しいシェルを起動しますが、クールでコンパクトであるという利点があります。

編集する:この回答は、各ファイルに対して新しいシェルを起動するので満足できません。これは2つのプロセスのみを実行する必要があります。

$ locate --regex --basename "xfce4-keyboard-overlay$" | xargs -i echo 'test -d "{}" && echo "{}"' | bash

もちろんインタプリタを完全に終了しないといいでしょうが、xargsコマンドを連結する機能は制限されているようです。

答え4

私の2セント:

while IFS= read i; \
do \
  if [ -f "$i" ]; \
  then \
    echo "$i"; \
  fi; \
done < <(locate --regex --basename "xfce4-keyboard-overlay$")

これがG-Manがフロー交換を統合する方法です。

関連情報