bashのファイル名展開メカニズムからいくつかのファイルを除外するにはどうすればよいですか?


14

ルートディレクトリにubuntuファイルシステムディレクトリがあり、誤って何百ものファイルをルートディレクトリにコピーしました。

私は直感的にファイルシステムを除外してコピーされたファイルを削除しようとしました

rm -rf !{bin,sbin,usr,opt,lib,var,etc,srv,libx32,lib64,run,boot,proc,sys,dev} ./.

動作しません。全体を削除しながらいくつかのディレクトリを除外する適切な方法は何ですか?

編集:何をすべきかを知らずに、ここでコマンドを実行しないでください!


1
どのシェルを使用していますか?ファイル名のグロビングは、そのような派手なことをする場合にはシェルに依存します。
クサラナナンダ

2
答えではありませんが、たとえばを使用しますmc。ですべてを選択し*-またはInsertキーで特定のファイルの選択を解除します。
pbm

1
「mc」とは何か説明できますか?
MikeP

@Kusalanandaそれはだ/bin/bash
KENN

3
@MikeP:mcミッドナイトコマンダー、ノートンコマンダーの非常に便利な模倣です。ターミナルで実行されます。(Midnight CommanderとNorton Commanderはどちらもオーソドックスファイルマネージャーと呼ばれるものの例です。)
AlexP

回答:


21

あなたが使用しているのでbash

shopt -s extglob
echo rm -rf ./!(bin|sbin|usr|...)

echoシステム全体を爆破する可能性のあるものを実行している場合は、コマンドラインの先頭に追加することをお勧めします。結果に満足したら削除します。

注:上記のコマンドでは、隠しファイル(ドットで始まる名前のファイル)は削除されません。それらも削除したい場合は、dotglobオプションも有効にします:

shopt -s dotglob

これを使用して、ファイルシステムを正常にクリーンアップしました。最初はディレクトリでテストしました。rm -rf ./!(bin,sbin,..)カンマ区切りも試しましたが、すべてのディレクトリが削除されます。
ケン

その!(...)構文は何ですか?私は直感的にls ./!(*/)ファイルのみをリストすると思った例から、それはそのように機能しません。
ジュスティ

@giustiこの構文は、ファイル名展開メカニズムの拡張パターンマッチングです。その説明は、パス名展開の章のbashマニュアルにあります。ファイルのタイプを除外するために使用することはできません*。スターや他のグロブと同様に、名前のみを除外します。
-jimmij

12

このコマンドは、/以下のディレクトリ以外のすべてを表示します。

find / -maxdepth 1 -type f

あなたが行ったら絶対に確認してください何のファイルが保存しておきたいことはありません、あなたが使用することができます。

find / -maxdepth 1 -type f -delete

より安全なのは、保存したいものを削除しないように、それらを他の場所に移動することです。

mkdir /root/preserve
find / -maxdepth 1 -type f -exec mv -- "{}" /root/preserve/\;

ファイルに加えて、ファイルシステムのルートに追加したディレクトリもある場合、LSBディレクトリを自動またはから除外することで自動化できますが、正直に言うと、ファイルシステムのルートである場合は、可能な限り手動で実行することを強くお勧めします。mvrm

これが実行可能でない場合、このような何かがトリックを行うことができます:

#!/bin/bash
declare -a excludes
for item in root sys 'lost+found' mnt home proc etc opt boot lib lib64 libx32 sbin media srv dev var usr bin tmp run; do
    excludes+=("$item")
done
if ! [[ -d /root/preserve ]]; then
    mkdir -p /root/preserve
fi
IFS="\n"
for item in find / -type d -maxdepth 1; do
    really=true
    for exclude in ${excludes[@]}; do
        if [[ "$exclude" == "${item#/}" ]]; then
            really=false
        fi
    done
    if [[ "true" == "$really" ]]; then
        mv -- "$item" /root/preserve/
    fi
done

悲鳴テストに合格すると(つまり、システムはまだ実行されていて、苦しんで悲鳴を上げていません)、のコンテンツを削除できます/root/preserve/

重要な注意:あなたが何をするにしても、の順列を実行することさえ考えないでくださいrm -fr [ANYTHING GOES HERE] /


ソリューションはファイルのみを削除しますが、周囲にもフォルダーがあります。
ケン

1
あまりにも何度も、私は貧しい人々から失望の悲鳴を聞いたことがありrmます。スクリプトのようrm -fr $somepath/somepath、それの初期化されていません。これがどれほど重大かを表現することはできたかもしれませんが、私の忠告では家族に優しいままでいることを選びました。
-DopeGhoti

3

これでジョブが完了するはずです(ただし、OPが要求する方法とは異なります)。

ls -1 >1.txt
pico 1.txt 

保持したいすべてのファイル/ディレクトリを削除します

xargs rm < 1.txt

すべてのファイルが同じ名前形式、日付、または他のものを持っている場合、他の方法があります。

私はiノードを調べます-そして、それらがls -i | sortを介してシーケンシャルかどうかを確認し、そうであれば、新しいファイルはより大きなiノードを持ちます。次に、上記と同じタイプのプロセスを使用して...

ls -iF1 | sort |cut -c10- | grep -vE "\/|\@" >i.txt   #This part removes entries that are not regular files, such as directories and links.  
pico i.txt
xargs rm < i.txt

上記のcutコマンドで、まずiノードリストをチェックして、適切な量であることを確認します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.