与えられた入力パターンに一致するディレクトリ内のすべてのファイルを繰り返しリストしたいと思います。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 = s
full 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
標準ファイル名パターンを使用します。ksh
bash
bash
ls
extglob
だからあなたはこれを行うことができます:
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=bar
。ls
"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
。