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


28

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

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

find -not -iname "*.txt"

または

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

動作するようです。しかし、どうすれば.txtファイルまたは .pdfファイルを除くすべてをリストできますか?私がいくつかの論理の並べ替え「または」で使用する必要があると思われるfindかをgrep


2
隠しドットファイルでは、lsvs findvsグロビングの動作が異なる場合があることに注意してください。
jw013

1
留意すべきもう1つのことはfind、再帰のようにサブディレクトリをトラバースしlsます。-maxdepth 1with findを使用して、のように動作させますls
jw013

したがって、再帰的ではなく、現在のディレクトリ内のファイルをリストするだけですか?
デイジー

回答:


28

の適切なバージョンがあると仮定するとls、これはおそらく最も簡単な方法です:

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

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

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

8
GNU lsオプションは移植性がありません。
バハマ

4
lsとにかく移植可能なスクリプトに実際には属していませんので、私はOPがインタラクティブな使用のみについて尋ねていると仮定していました。
jw013

1
lsが移植できないのはなぜですか?それから何を使うべきですか?
フリード

28

サポートを探す -o

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

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

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

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

1
ありがとう!の出力を解析しないのはなぜlsですか?
アンドリュー

6
最初に@Andrewが壊れやすいため(改行を含むファイル名-はい、それが有効なファイル名である-findの-print0 / -exec / -delete / etc。がその問題を回避します)。第二に、通常はより簡単な方法があるためです。
デロバート

findマンページに加えて、docstore.mik.ua / orellyfind
ワイルドカード

人間のための声明を解読するためだけに:find . NOT ( *.txt OR *.pdf )
ウィスバッキー

12

bash(とオンにグロブ延長shopt -s extglob)、グロブが!(*.txt|*.pdf)動作するはずです。このグロブは、を含むがこれに限定されないファイル引数を取る任意のコマンドに直接渡すことができますls


1
+1ですが、サブディレクトリがある場合、その内容もリストされます。使用-dを避けるためにその:ls -d !(*.txt|*.pdf)
legends2k

ありがとう、私は正確に複数のファイルを受け入れる構文を探していた、これはここにうまく合うだろうstackoverflow.com/questions/216995/…-
フリード

6

zshextendedglob

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

または

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

またはkshglob(はい、それは「bash拡張グロビング」ではなくkshグロビングです):

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

ただし、これらはドットファイルも除外することに注意してください。

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

FIGNORE='@(.|..|*.txt|*.pdf)'
printf '%s\n' *


3

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

GNU(およびいくつかのBSD)find-print0NUL文字で終了するファイル名を印刷するように指示する述語をサポートします。この文字はファイル名内では許可されず、衝突がないことを保証します。他のコマンドは、NULを入力区切り文字として使用するように指示できます。

最も重要なのはGNU xargsです。指定されたコマンドを実行し、コマンドライン引数としてファイルのリストを渡します。xargs -r0findの-print0例と組み合わせて実行したい場合例:

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

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

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

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

これにより、名前が.tar.gzで終わらないすべてのファイルのtar.gzファイルが作成されます

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


tarコマンドの例は、良いものです。ただし、ほとんどの目的に-execは、より適しています。
ワイルドカード

1

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

ls !(*.pdf|*.txt)

動作するはずです!

しかし

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

一般的な方法です。


0

補足として、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環境変数を変更しないために、このコマンドをサブシェルとして(括弧を使用して)実行することに注意してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.