web-dev-qa-db-ja.com

指定された拡張子を持つものを除いて、ディレクトリ内のすべてのファイルを一覧表示するにはどうすればよいですか?

。txt。pdf、およびその他のファイルを含むフォルダーがあるとします。 「その他」のファイル(つまり、拡張子。txtまたは。pdfを持たないファイル)を一覧表示したいと思います。これを行う方法について何かアドバイスはありますか?

特定の拡張子を持たないファイルをリストする方法を知っています。たとえば、。txtファイル以外のすべてのファイルを一覧表示する場合は、

find -not -iname "*.txt"

または

ls | grep -v '\.txt$' | column

動作するようです。しかし、。txtファイルまたは。pdfファイル以外のすべてをどのようにリストできますか? findまたはgrepで論理的な「or」を使用する必要があるようです。

31
Andrew

GNU lsとすると、これはおそらく最も簡単な方法です。

ls -I "*.txt" -I "*.pdf"

すべてのサブディレクトリを反復処理する場合:

ls -I "*.txt" -I "*.pdf" -R
31
Dejian

サポートを探す-o

find . ! '(' -name '*.txt' -o -name '*.pdf' ')'

優先順位を正しくするには、括弧が必要です。 Findは多くのことを行います。マンページを読むことをお勧めします。

またはgrepでも実行できます(ただし、実際には ls の出力を解析しないでください)

ls | grep -Ev '\.(txt|pdf)$' | column
30
derobert

bash拡張グロビング(_shopt -s extglob_でオン)を使用すると、グロブ!(*.txt|*.pdf)が機能するはずです。このグロブを、lsを含むがこれに限定されない、ファイル引数を取る任意のコマンドに直接渡すことができます。

12
jw013

zshextendedglob

print -rl -- *~*.(txt|pdf)

または

print -rl -- ^*.(txt|pdf)

またはkshglobを使用(はい、つまり、「bash拡張グロビング」ではなくkshグロビングです):

print -rl -- !(*.txt|*.pdf)

ただし、ドットファイルは除外されます。

ksh93にはFIGNORE(誤)機能があります。

FIGNORE='@(.|..|*.txt|*.pdf)'
printf '%s\n' *
6
Thor
find /path/to/directory '!' -name '*.pdf' '!' -name '*.txt'

De Morganの法則 のため、これはOR演算子を使用したコマンドと同じです。

4
Francesco Turco

Derobertが提案したように、最善の策はfindを使用することです。ただし、実際にはcanは他のコマンドを使用してパイプラインで結果を使用します。

GNU(および一部のBSD)findは、_[〜#〜] nul [〜#〜]文字で終了するファイル名を出力するように指示する-print0述語をサポートします。ファイル名内で許可され、衝突がないことを保証します。他のコマンドは、入力区切り文字として[〜#〜] nul [〜#〜]を使用するように指示できます。

最も重要なのはGNU xargsです。これは、指定したコマンドを実行し、ファイルのリストをコマンドライン引数としてそれに渡します。xargs -r0を検索の-print0例:

find . -type f ! \( -name \*.pdf -o -name \*.txt \) -print0 | xargs -r0 ls -ld

これにより、すべてのpdfおよびtxtファイルの長いディレクトリリストが安全に印刷されます。名前にスペースや印刷できない文字が含まれるファイルも含まれます。

次のようにGNU tarとともに使用することもできます。

tar -zcf myarchive.tar.gz --null --files-from <(
  find . -type f ! -name \*.tar.gz -print0)

これは、名前が.tar.gzで終わらないすべてのファイルのtar.gzファイルを構築します。

rsyncは、他のいくつかのファイルと同様に、-0パラメータを使用してnullで区切られたファイルも受け入れます。しかし、xargsは、このタイプの目的で通常使用する接着剤です。それかfind-exec機能のどちらかです。

3
tylerl

サブディレクトリがない場合

ls !(*.pdf|*.txt)

うまくいくはずです!

だが

ls -I "*.pdf" -I "*.txt"

一般的な方法です。

0
abu_bua

補足として、bash互換シェルを使用している場合は、GLOBIGNORE変数を使用して、パターンマッチングから結果を除外できます。男から:

   GLOBIGNORE
          A colon-separated list of patterns defining the set of filenames
          to be ignored by pathname expansion.  If a filename matched by a
          pathname  expansion  pattern also matches one of the patterns in
          GLOBIGNORE, it is removed from the list of matches.

あなたの特定のケースでは:

sh$ (GLOBIGNORE='*.pdf:*.txt'; ls -d *)

対話型シェルのGLOBIGNORE環境変数を変更しないようにするために、このコマンドをサブシェル(括弧を使用)として実行していることに注意してください。

0
Sylvain Leroux