リストにないすべてのファイルとフォルダを削除する

リストにないすべてのファイルとフォルダを削除する

保存したいパスを含むテキストファイルがある場合は、次のようにします。

/mnt/cache/vfs/cf/A/file
/mnt/cache/vfs/cf/B/file2

/mnt/cache/vfs/cf私のテキストファイルにない内容を除いて、以下のすべての内容を消去したいと思います。

だから/mnt/cache/vfs/cf/Z/file3削除されたなど。

テキストファイルが大きく、ファイル名にスペースや、アクセントやその他の特殊文字が含まれています。

答え1

ファイルシステムのファイルを一覧表示し、アーカイブしたいファイルセット内のファイルを削除し、残りを削除します。

xargsここでは、スペースを含むファイル名とスペースで区切られた部分の間に混乱がないように常にNULLで終わるファイル名を使用します。

find /mnt/cache/vfs/cf -type f -print0 |
    LC_ALL=C sort -z |
    LC_ALL=C comm -z -23 - <(LC_ALL=C sort list-of-files-to-keep.list | tr '\n' '\0') |
    xargs -0 printf '%s\n' {}

削除を実行する準備ができたらに置き換えますprintf '%s\n'rm --

このcommコマンドは、2つのソートされたファイルをインポートし、1行ずつ比較します。出力の最初の列は最初のファイルの項目のみ、2番目の列は2番目のファイルの項目のみ、3番目の列は2つのファイルの項目です。-1-2および修飾子は-3その列の出力を抑制するので、最初のcomm -23ファイル(-、つまり標準入力)。

私はロケールがC互いに一貫した方法で動作するように強制し(sort入力ソートが必要)、各行を決定的な方法でソートしました(一部のロケールは文字セットを同じ方法でソートするため、このような文字セットは次のようにソートできます)。一貫性のない方法)。commcomm

答え2

次のように単純なシングルライナーを使用します。

for FILE in $(ls /mnt/cache/vfs/cf); do grep "$FILE" keep_files.txt || rm "/mnt/cache/vfs/cf/$FILE"; done

ただし、削除するファイルの数に応じて、必要なファイルを誤って削除しないように、常に一時ディレクトリに移動することをお勧めします。 :)

答え3

私は何をしますか:

shopt -s extglob
cd /mnt/cache/vfs/cf
{   printf 'rm !('; awk -F'/mnt/cache/vfs/cf' '{print $2}' file |
    paste -sd '|'
} | sed 's/$/)/'

出力がうまくいけば、完全なコードスニペットを取得できますbash

shopt -s extglob
cd /mnt/cache/vfs/cf
{   printf 'rm !('
    awk -F'/mnt/cache/vfs/cf' '{print $2}' file |
    paste -sd '|'
} | sed 's/$/)/' | 
    bash

バラよりhttp://mywiki.wooledge.org/glob#extglob
そしてhttps://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html

関連情報