再帰 ls の負の extglob パターンに一致するすべての項目を無視します。

再帰 ls の負の extglob パターンに一致するすべての項目を無視します。

与えられた入力パターンに一致するディレクトリ内のすべてのファイルを繰り返しリストしたいと思います。lsを使う。 (ああ、これはBashにあります)。

lsでこれを行うことができると考える唯一の方法は、拡張globの否定モードでオプションをshopt -s extglob使用することです。無視すると否定するには少し迂回しているように見えますが、そうでなければワイルドカードは繰り返されません。ls --ignore=pattern!( pattern-list )

検索するディレクトリdirと一致させるパターンがすでにあると仮定すると、fileこれは現在の試みです。

ls -AR --ignore='!('"${file}"')' ${dir}

しかし、これは望む効果が得られないようです。たとえば、テストケースでは、ディレクトリ構造は次の出力を提供しますls -AR

    .:
    a  a.c  b  b.c  c  c.h  s

    ./s:
    a  a.c  b  b.c  c  c.h

file = *.c( dir = sfull command : ) を使った私のコマンドは、ls -AR --ignore=!(*.c) s次のような出力を提供します。

    ./s:
    a  a.c  b  b.c  c  c.h

私はこれをgrepに簡単に入力し、次のようなことをして、次のような出力を得ることがls -AR s | grep -v '.*.c'できることを知っています。

    s:
    a
    b
    c
    c.h

しかし、私はこれを行う方法を探していますls

完全に不明であれば申し訳ありません。 StackExchange サイトを初めて訪問しました。

よろしくお願いします!

答え1

globstarディレクトリの内容を自動的にリストしないように、シェルオプションと-dフラグを追加するのはlsどうですか?

shopt -s extglob
shopt -s globstar
ls -d  **/!(*.c)

答え2

GNUオプションは、拡張ファイル名パターンではなくls --ignore標準ファイル名パターンを使用します。kshbashbashlsextglob

だからあなたはこれを行うことができます:

ls -AR --ignore='*.[ch]' --ignore='*.cpp'

ただし、次の場合は次のことはできません。

ls -AR --ignore='!(*.[ch]|*.cpp)'

これは、次の名前のファイルのみを無視します!(foo.c|bar.cpp)

ではls -AR --ignore=!(*.c)スキーマが参照されていないため、 にbash渡す前にスキーマを拡張しようとしますls。したがって、現在のディレクトリで名前が.で始まり、"--ignore="終わらないファイルを見つけます".c"。たとえば、2つのファイル(1つは名前が付けられ、--ignore=fooもう1つは名前が付けられています)がある場合、、、4つのパラメータを使用して実行されます--ignore=barls"ls""-AR""--ignore=bar""--ignore=foo"

あなたはそれを行うことができます(GNU findを使用して)。

find . -regextype posix-extended -regex '.*\.([ch]|cpp)' -ls

またはPOSIXを使用してくださいfind

find . \( -name '*.[ch]' -o -name '*.cpp' \) -exec ls -ld {} +

あるいは、ディレクトリへのシンボリックリンクがないとします。

shopt -s extglob globstar dotglob failglob
ls -ld -- **/*.@([ch]|cpp)

今回は、bashワイルドカードパターンが実際に拡張され、ファイルリストがls

関連情報