ls コマンド結果の補数を取得します。

ls コマンド結果の補数を取得します。

複数のファイルを含むディレクトリがあるとします。すべてのファイルは、バイナリファイル(拡張子が宣言されていないファイル)とソースファイル(拡張子が宣言されて.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 /で導入)で見つかりますが、findPOSIXでは指定されていません。もう1つの方法は、Stéphaneが自分の意見で述べたように、検索操作を使用することです。呼び出し回数が大幅に減少するため、フォーマットを使用することを忘れないでください。 (ファイル名を末尾に配置できる構文を許可する必要があります。そうでない場合はラップする必要があります。通話中)。findxargs-exec-exec command {} +commandcommandsh -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オプションを使用すると、エスケープが必要な可能性のあるファイル名のすべての文字を処理できるため、おそらくこれが最良のオプションです(そして、findNULLxargsで終わる文字列で作業できる場合 - GNUツールはです)。

答え2

では、ksh以下を使用できます。

rm -- !(*.c|*.md)

bashこれらのワイルドカード拡張は、aftershopt -s extglobおよびzshafterでも使用できますsetopt kshglob

以下はzshデフォルトの対応するエントリです。

setopt extended_glob
rm -- ^(*.c|*.md)

!extglobにあるのは「not」です。元のコマンドでは、次のように書くことをお勧めします。

rm -- *.c *.md

解析された出力はls信頼できず、一部のファイル名で中断されます。バッシュウィキをご覧くださいlsを解析する

関連情報