指定された文字列を含まないファイル名の検索

指定された文字列を含まないファイル名の検索

私はその反対をしたい:

find . -name "*2013*"

名前に文字列 "2013"が含まれていない現在のディレクトリ内のすべてのファイルを見つけます。どうすればいいですか?

答え1

簡単に:

find . ! -name '*2013*'

追加すると、! -type dその種類のファイルを除外することもできます。目次(そのまま.)または-type fそのまま含める定期的な他のすべての種類のファイル(ディレクトリ、fifo、シンボリックリンク、デバイス、ソケット...)を除くファイル。

*ただし、ゼロ個以上のシーケンスを一致させるように注意してください。数値。したがって、現在のロケールで有効な文字で完全にデコードできないコンテンツの2013前後のファイル名を報告できます。2013

文字を複数バイトにエンコードできるロケール(UTF-8など)にあり、ファイル名が別のエンコーディングにある場合、これが発生する可能性があります。たとえば、少なくともUTF-8ロケールおよびGNUシステムでは、ファイルがStéphane2013iso8859-15文字セット(0xe9バイト)でエンコードされている場合、システムはファイルを報告します。é

ファイル名がロケールの文字セットでエンコードされていることを確認するのが最善ですが、これが保証できない場合は、回避策はfindCロケールで実行することです。

LC_ALL=C find . ! -name '*2013*'

2013デフォルト名だけでなく、パスの任意の場所からファイルを除外するには、次のようにします。

LC_ALL=C find . ! -path '*2013*'

これはより効率的です:

LC_ALL=C find . -name '*2013*' -prune -o -print

つまり、名前が含まれるfindディレクトリ2013pruneツリーの該当部分)にあえて入れないように指示されます。なぜならパスに2013


1 何百ものマルチバイト文字があります2

答え2

Kshファイル名パターンで十分です。

# files with 2013
ls -d -- *2013*

# files without 2013
ls -d -- !(*2013*)

引用する

シェルがbashの場合は、このモードを使用する前にbashを実行する必要がありますshopt -s extglob(シェルに入れることができます.bashrc)。シェルがzshの場合は実行する必要がありますsetopt ksh_glob(に入れることができます.zshrc)。 Zshも提供されるので、ls -d -- ^*2013*事前準備が必要ですsetopt extended_glob

これらのファイル名で実行する操作によっては、lsこれは正しいコマンドではない可能性があります。配列に保存

filenames=( !(*2013*) )
for f in "${filenames[@]}"; do ...; done

答え3

findの代替案は、一致の意味を変更して一致しない行を選択するpipingオプションを使用すること!です。egrep-v

find . | egrep -v 2013

ここでの利点は、egrepのすべての機能を使用して目的の方法で出力をフィルタリングすることです。

答え4

現在のディレクトリで特定の文字列を含まないすべてのファイルを探します(ここでは「2013」)。

find . ! -name "*2013*" -type f

関連情報