web-dev-qa-db-ja.com

特定のものを除くすべてのファイルとディレクトリを削除するBashスクリプト

特定のディレクトリにcdする非常に単純なBashシェルスクリプトを作成しようとしています。選択したいくつかのファイルとディレクトリを除くすべてのファイルとディレクトリを削除してから、元のディレクトリにcdで戻します。

私のコードは:

_#!/bin/bash 
cd /path/to/desired/directory
shopt -s extglob
rm !\(filename1\|filename2\|filename3\) -rf
cd -
_

記号 '('および '|'を一重引用符または二重引用符または円記号で記述するさまざまな方法を試しましたが、何も機能しませんでした。_shopt -s extglob_およびrm !(filename1|filename2) -rfはスクリプトの外部では正常に機能することに注意してください。

おそらく、私には見えない標準的で基本的なbashスクリプトのエラーを犯していますが、経験はこれからです...

助言がありますか!?前もって感謝します。

10
mario go

私がすぐに見ることができる2つの問題:

  • rmへの-rf引数は必ず来なければなりませんファイル名
  • Extglob指定子!(|、および)は、バックスラッシュでエスケープする必要がありますnot

代わりにこれを試してください:

rm -rf !(filename1|filename2|filename3)

それでも機能しない場合は、-f引数を削除すると、何が問題になっているのかを黙って抑制するのではなく、エラーメッセージが表示されます。削除された各ファイルの名前を印刷するには、-vオプションを追加することもできます。

8
Adam Rosenfield

findの最新バージョンをお持ちの場合は、以下を使用してください。

find . -not -regex "filename1|filename2|filename3" -print

出力を確認し、本当に削除したいファイルのみを出力する場合は、-print-deleteに置き換えます。

お使いのバージョンのfind-deleteをサポートしていない場合は、-type f -exec rm "{}" \;を使用してください

これはファイルのみを削除することに注意してください。これは重要です。ファイルxを保持すると言っても、そのファイルがyフォルダーにある場合、xは無視され、後でフォルダー全体で削除されますy

すべての空のフォルダを削除するには(そしてこれにより、保持したいファイルが保持されます):

find . -type d -empty -exec rmdir "{}" \;

(出典: nixで空のディレクトリとファイルを見つけて削除する方法

3
Aaron Digulla

特定のファイルを免除するルールを作成することはお勧めしません。私がする可能性が高いのは、ファイルマスク/グロブ、または削除したいファイルの名前にある他のアンカーのいずれかを見つけようとすることです。これらのアンカーは、保持したいファイルにはありません。ほとんどの場合、拡張によってそれを行うことができます。残念ながら、どのファイルの名前も言及されていないため、具体的にはお役に立てません。

2つ(またはそれ以上)の検索ループのようなもの:-

find *.mp3 d.mp3 -maxdepth 1 -type f | while read mp3s
do
mv $mp3s ~/d.stuff-to-keep
done    

find *.txt d.mp3 -maxdepth 1 -type f while read textfiles
do
rm -v $textfiles
done

そうでない場合は、ファイルの他の一般的な特性を探します。存在しない場合は、ファイルの名前を変更して自分に変更する必要がある場合があります。私はいつもファイル名にたくさんのアンカー(分離された名前フィールド、拡張子など)を入れています。そうすることで、必要なことを行うためのさまざまな方法がたくさんあるからです。私の通常の名前の形式は次のとおりです。-

<extension>.+<author>+<year>+<work-name>+<volume-number>+<number-of-volumes>

プラス記号はフィールド区切り文字であり、ダッシュはスペース用ですが、最初または最後の文字としてダッシュはありません。すべて小文字で、制御文字やその他の英数字以外は使用できません。その結果、awk、cut、またはその他の使用したいものでそれらを切り取り、簡単に名前を変更できます。名前の先頭に拡張子を付けることは、完全に順序付けられたファイルシステムを取得するためにlsが1つのフラグ(-l)のみを必要とすることも意味します。

基本的なPOSIXツールを使用してディレクトリ構造をデータベースとして使用する方法を知っている場合は、必要なことを実行するために、より複雑なものをインストールする必要がない場合があります。

UNIXでは、ファイル名に長い文字制限があり、長い名前をナビゲートするためのタブ補完があります。それらの両方を自由に使用することを恐れないでください。

1
petrus4

ファイルがあると仮定します。

drwxr-xr-x2ルートルート4096Feb 1 02:17 a

drwxr-xr-x2ルートルート4096Feb 1 02:17 b

drwxr-xr-x2ルートルート4096Feb 1 02:17 c

drwxr-xr-x2ルートルート4096Feb 1 02:17 d

drwxr-xr-x2ルートルート4096Feb 1 02:17 e

drwxr-xr-x2ルートルート4096Feb 1 02:17 f

drwxr-xr-x2ルートルート4096Feb 1 02:18 nodelete1

drwxr-xr-x2ルートルート4096Feb 1 02:18 nodelete2

あなたができること:

ls | grep -v "nodel.\+" | xargs rm -rf

高度な正規表現構文を使用してファイルを除外します。

説明:

ls ---現在のディレクトリを一覧表示します(ディレクトリのみを一覧表示するにはls -d)

grep -v --- vフラグは、-Pフラグを指定した場合に一致しない+ grepがPerlスタイルの正規表現を書き込むことを許可するものを指定します

xargs ---各アイテムにアクション「rm-rf」を適用します

0
Mr. BeatMasta

以下をお試しください:

for i in `ls | grep -v "file1\|file2\|file3"` ; do rm -rf $i; done

幸運を!

0
Nancy