ディレクトリから空のファイルをすべて削除するには?

ディレクトリから空のファイルをすべて削除するには?

誤ってシェルに貼り付け、名前がすべて乱数の空のファイルの束を作成しました。これらすべてを一度に削除する効果的な方法は何ですか?

ディレクトリに必要な他のファイルがあります。そのファイルには数字がありますが、数字で始まるファイルはすべて間違っています。正規表現の削除が好きですか?

答え1

削除したいファイルが空であるということです。これらのファイルを削除する1つの方法は、空のファイルのみを削除することです。これにより、コンテンツを含むファイルは削除されません。私はこれが名前で分類するよりも安全であると信じています。現在のディレクトリから空のファイルを削除するコマンドは次のとおりです。

find ./ -size 0 -delete

Stéphane Chazelasは建設的なコメントを提供しました。より良いコマンドは次のとおりです。

find ./ -maxdepth 1 -type f -size 0 -delete

答え2

そしてzsh

rm -f -- *(.L0)

削除されます定期的な.)非表示の空のファイル(L長さ0)。

内部bashシェルまたは他のシェル:

zsh -c 'rm -f -- *(.L0)'

名前がASCII 10進数でのみ構成されているファイル1を削除するには:

rm -f <->

ここでは特定の範囲内の数字<->と一致しますが、境界はありません。<x-y>同様に他のシェルにもzsh -c '...'

では、bash次のこともできます。

(shopt -s extglob failglob; rm -f +([0123456789])

またはksh93:

rm -f ~(N)+([0123456789])

2つを組み合わせることができます(すべての数字を含む空の一般的なファイルを削除します)。

rm -f <->(.L0)

POSIXシェルとユーティリティの場合、それに対応する内容は次のとおりです。

LC_ALL=C find . ! -name . -prune -type f -size 0c \
  ! -name '*[!0-9]*' -exec rm -f {} +

すべての数字で構成されるファイルを見つけるには、1つ以上の数字以外のファイルを含むファイルを除くすべてのファイルを見つけます。-size 0cサイズのファイルと一致バイト²は0です。

LC_ALL=C範囲に0123456789のみが含まれていることを確認し0-9、さらに重要なのは、ファイル名がロケールとは異なる文字セットにエンコードされている場合、コマンドが機能することです。たとえば、これがない場合、GNUおよびUTF-8ロケールでは(latin1でエンコードされた)ファイルは、find数値以外の文字が見つからず(数値以外の文字のみで構成されている)削除されます。文字でデコードできない0xe9バイト(0個以上の文字と一致)は一致しません。$'St\xe9phane'Stéphane*

zshglob は、文字の一部を形成しないバイトが特殊文字の一部の形式で処理されるため、問題はありません。一方、bash globおよび現在のバージョンでは、bash入力文字列を文字としてデコードできない場合はバイト単位に切り替わります。一致(C言語環境と同じように動作させる)。


¹今回はこれに限定されません。定期的なファイル(シンボリックリンクを含む)、fifos ...ファイルタイプ目次rmただし、そのオプションを渡さないと、ディレクトリは削除されないため削除されません-r

-size 0²サイズは丸められているため、ここでも機能する(サイズは512バイトから0)を使用することもできます。戻るしたがって、現在では、バイトサイズのファイルは512バイト単位で構成されていると見なされますが、より一般的には正確なサイズ一致のために対応するサフィックスを-size 0使用することをお勧めします。たとえば、512ファイルサイズのファイルには適用されません。サイズは1から512までです。サイズが正確に512のファイルの場合。 glob修飾子の場合、基本単位は次のとおりです。c-size 1-size 512czshLバイト、512バイト単位ではありません。

答え3

グローブが使えます。例えば

echo rm [0-9]*

echoアーカイブしたいアイテムが削除されないことを確認したら、削除してください。ただし、rmエイリアス(偶発的なファイルの削除に対する非常に一般的な保護)がある場合は、上書きするのではなくrm -i実行する必要があります。それ以外の場合は、各ファイルに入力する必要があります。command rm [0-9]*rm [0-9]*y

または、mvファイルを新しく作成されたディレクトリに配置し、保持したいファイルを個別に元の場所に移動してからディレクトリを削除します。例えば

mkdir /tmp/junk
mv [0-9]* /tmp/junk
cd /tmp/junk
# investigate and mv any you want to keep
cd -
rm -rf /tmp/junk

他の選択肢:

単一のbashコマンドラインで受け入れ可能なものより多くのファイルを削除するには、次の手順を実行します。

for i in {0..9}; do rm "$i"*; done

または

find . -maxdepth 1 -type f -empty -name '[0-9]*' -delete

または試用版:

find . -maxdepth 1 -type f -empty -name '[0-9]*' -print | less

この-maxdepth 1オプションは、findがサブディレクトリに繰り返されるのを防ぎ、通常の-type fファイル(ディレクトリ、ソケット、名前付きパイプなどではない)のみを一致させるように制限し、空のファイルのみが一致することを-empty確認します。

または:findmv

mkdir /tmp/junk
find . -maxdepth 1 -type f -empty -name '[0-9]*' -exec mv -t /tmp/junk/ {} +

(GNUには、移動するファイルのリストの前にターゲットディレクトリを指定するオプションがmv必要です。GNU mvはLinuxの標準です。)-t

答え4

数字で始まるすべてのファイルを削除するには、bashforループを使用する1つの方法があります。

for n in [0-9]* ; do rm -i "${n}" ; done

シェル glob [0-9]* (数字の後に 1 つ以上のランダム文字が続くことを意味します) と一致するすべてのファイルを繰り返します。各ファイル(安全のために暫定的に$n""と呼ばれる)ごとにそのファイルを削除します。ファイル全体のロードを自動的に削除するのは少し慎重なので、インタラクティブに-iを追加しましたが。${n}あなたはあなたの裁量でこのコンテンツを削除することができます。

さらに安全にするには、削除する前に各ファイルが空であることを確認してください。

for n in [0-9]* ; do if [[ `ls -l "${n}" |sed 's/[^ ]* [^ ]* [^ ]* [^ ]* \([0-9]*\) .*/\1/'` -eq 0 ]] ; then rm "${n}" ; fi ; done

次に、各ファイルに対して置換sedを介して長いリストを渡し、行を5番目のフィールド(ファイルサイズ)に置き換えて、0に等しいかどうかをテストします。その場合は、各ファイルの後に「はい」と答えずに安全に削除できます。

これは私にとって効果的でしたが、アーカイブしたい他のファイルに囲まれた多数のファイルを削除する場合は、正しいファイルが選択されていることを確認することから-i始めることをお勧めします。それからCtrl-C楽になれば-i

または、ディレクトリをバックアップしてコピーに対してコマンドを実行し、diff -rバックアップを削除する前に問題がないことを確認してください。

関連情報