web-dev-qa-db-ja.com

Linux上のBashで複数のファイルを一度に削除する方法は?

Linuxサーバー内に次のファイルのリストがあります。

abc.log.2012-03-14
abc.log.2012-03-27
abc.log.2012-03-28
abc.log.2012-03-29
abc.log.2012-03-30
abc.log.2012-04-02
abc.log.2012-04-04
abc.log.2012-04-05
abc.log.2012-04-09
abc.log.2012-04-10

コマンドrm -rfを使用して、選択したログファイルを1つずつ削除しています。以下を参照してください。

rm -rf abc.log.2012-03-14 
rm -rf abc.log.2012-03-27
rm -rf abc.log.2012-03-28

選択したファイルを一度に削除できるようにする別の方法はありますか?

91
user1253847

Bashは、あらゆる種類のワイルドカードと拡張をサポートしています。

正確なケースは ブレース展開 で処理されます。

$ rm -rf abc.log.2012-03-{14,27,28}

上記はexpand to3つの引数すべてを持つ単一のコマンドに展開され、入力と同等です:

$ rm -rf abc.log.2012-03-14 abc.log.2012-03-27 abc.log.2012-03-28

rmがロードされる前に、この展開がシェルによって行われることに注意することが重要です。

144
unwind

ワイルドカード(*)を使用して、複数のファイルを一致させます。

たとえば、次のコマンドは、名前がabc.log.2012-03-で始まるすべてのファイルを削除します。

rm -f abc.log.2012-03-*

rmコマンドを実行する前に、削除する内容を確認できるように、ls abc.log.2012-03-*を実行してファイルをリストすることをお勧めします。

詳細については、Bashの ファイル名展開 のmanページをご覧ください。

72
dogbane

特定のフォームに名前が一致するすべてのファイルを削除する場合は、ワイルドカード(globパターン)が最も簡単なソリューションです。いくつかの例:

$ rm -f abc.log.*             # Remove them all
$ rm -f abc.log.2012*         # Remove all logs from 2012
$ rm -f abc.log.2012-0[123]*  # Remove all files from the first quarter of 2012

正規表現はワイルドカードよりも強力です。 grepの出力をrm -fにフィードできます。たとえば、ファイル名の一部が"abc.log"で始まり、一部が"ABC.log"で始まる場合、grepを使用すると、大文字と小文字を区別しない一致を実行できます。

$ rm -f $(ls | grep -i '^abc\.log\.')

これを行うとき、最初にls | grep ...コマンドを実行し、必要な出力が生成されることを確認します-特に私がrm -fを使用している場合:

$ ls | grep -i '^abc\.log\.'
(check that the list is correct)
$ rm -f $(!!)

ここで、!!は前のコマンドに展開されます。または、上矢印またはCtrl-Pを入力し、前の行を編集してrm -fコマンドを追加できます。

これは、bashシェルを使用していることを前提としています。他のシェル、特にcshとtcsh、およびいくつかの古いsh派生シェルは、$(...)構文をサポートしない場合があります。同等のバックティック構文を使用できます。

$ rm -f `ls | grep -i '^abc\.log\.'`

$(...)構文は読みやすく、もしあなたが本当に野心的であれば、ネストすることができます。

最後に、削除するファイルのサブセットを正規表現で簡単に表現できない場合、私がよく使うトリックは、ファイルを一時テキストファイルにリストしてから編集することです。

$ ls > list
$ vi list   # Use your favorite text editor

その後、listファイルを手動で編集し、削除するファイルのみを残してから、次の操作を実行できます。

$ rm -f $(<list)

または

$ rm -f `cat list`

(これは、ファイル名に面白い文字、特にスペースが含まれていないことを前提としています。)

または、listファイルを編集するときに、各行の先頭にrm -fを追加してから、次のことができます。

$ . ./list

または

$ source ./list
36
Keith Thompson

崇高な複数行選択を使用して、すべてのファイルを1行に結合し、各ファイル名の間にスペースを追加してから、リストの先頭にrmを追加します。これは、削除するファイル名にパターンがない場合に最も役立ちます。

[$]> rm abc.log.2012-03-14 abc.log.2012-03-27 abc.log.2012-03-28 abc.log.2012-03-29 abc.log.2012-03-30 abc.log.2012-04-02 abc.log.2012-04-04 abc.log.2012-04-05 abc.log.2012-04-09 abc.log.2012-04-10
7
Andy

ワイルドカードはこれにはうまく機能しますが、安全のために、ワイルドカードの使用はできる限り最小限にすることが最善であるため、次のようになります。

rm -rf abc.log.2012-*

見た目からは、これらはただの単一ファイルですか?これらの項目のいずれもディレクトリでない場合、再帰オプションは必要ないはずです。そのため、安全のためだけに、それを使用しないことが最善です。

5
lacrosse1991

私はLinuxの第一人者ではありませんが、出力ファイルのリストをxargs rm -rfにパイプしたいと考えています。私は過去にこのようなものを使用して良い結果を得ました。最初にサンプルディレクトリでテストしてください!

編集-表示されている他の回答に基づいて、誤解している可能性があります。ワイルドカードを使用できる場合、素晴らしい。表示された元のリストは、「選択」を提供するプログラムによって生成されたと想定したため、xargsへのパイピングが進むべきだと思いました。

2
Dave