保存したいパスを含むテキストファイルがある場合は、次のようにします。
/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
入力ソートが必要)、各行を決定的な方法でソートしました(一部のロケールは文字セットを同じ方法でソートするため、このような文字セットは次のようにソートできます)。一貫性のない方法)。comm
comm
答え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