複数のファイルを含むディレクトリがあるとします。すべてのファイルは、バイナリファイル(拡張子が宣言されていないファイル)とソースファイル(拡張子が宣言されて.c
いる)です。私はこうする:
$ ls
そして得る:
README.md hello-world.c hello-world get-name.c get-name
.c
特定の拡張子(たとえば、および)を持つファイルのみをリストしたいと思います.md
。次の操作を行います。
ls *.c *.md
それは重要ではありません!
しかし、今すべてのファイルを削除したい場合はどうすればよいですか?欲しくない.c
または拡張機能がありますが、.md
どうすればよいですか?
私は次の拡張子を持つファイルを処理する方法を知っています。
ls *.c *.md | xargs rm
しかし、そのファイルを削除するようにコマンドラインにどのように指示しますか?いいえ私の基準に合いますか?
答え1
使用find
:
find -maxdepth 1 ! -name "*.c" -print0 | xargs -0 ...
-maxdepth
、、、-print0
および-r
はいくつかの-0
実装(GNU /で導入)で見つかりますが、find
POSIXでは指定されていません。もう1つの方法は、Stéphaneが自分の意見で述べたように、検索操作を使用することです。呼び出し回数が大幅に減少するため、フォーマットを使用することを忘れないでください。 (ファイル名を末尾に配置できる構文を許可する必要があります。そうでない場合はラップする必要があります。通話中)。find
xargs
-exec
-exec command {} +
command
command
sh -c
またはgrep
出力ls
ls | grep -v "\.c$" | xargs ...
正規表現を使用して複数の拡張子をフィルタリングできます。
... | grep -v "\.\(c\|md\)$" | ...
拡張正規表現を使用してください。
... | grep -Ev "\.(c|md)$" | ...
固定文字列オプションを使用します(ファイル名の末尾のみが一致しません!)。
... | grep -vF ".c
.md" | ...
またはより多くを接続してgrep
:
... | grep -v "\.c$" | grep -v "\.md$" | ...
つまり、find
この-print0
オプションを使用すると、エスケープが必要な可能性のあるファイル名のすべての文字を処理できるため、おそらくこれが最良のオプションです(そして、find
NULLxargs
で終わる文字列で作業できる場合 - GNUツールはです)。
答え2
では、ksh
以下を使用できます。
rm -- !(*.c|*.md)
bash
これらのワイルドカード拡張は、aftershopt -s extglob
およびzsh
afterでも使用できますsetopt kshglob
。
以下はzshデフォルトの対応するエントリです。
setopt extended_glob
rm -- ^(*.c|*.md)
!
extglobにあるのは「not」です。元のコマンドでは、次のように書くことをお勧めします。
rm -- *.c *.md
解析された出力はls
信頼できず、一部のファイル名で中断されます。バッシュウィキをご覧くださいlsを解析する。