フォルダーを定期的にクリーンアップする必要があります。テキストを含むファイルリストを取得し、どのファイルが許可されています。次に、このファイルにないすべてのファイルを削除する必要があります。
例:
dont-delete.txt
:
dontdeletethisfile.txt
reallyimportantfile.txt
neverdeletethis.txt
important.txt
私のフォルダはクリーンアップを行います例としてこれが含まれています:
ls /home/me/myfolder2tocleanup/
:
dontdeletethisfile.txt
reallyimportantfile.txt
neverdeletethis.txt
important.txt
this-can-be-deleted.txt
also-waste.txt
never-used-it.txt
したがって、このファイルは削除する必要があります。
this-can-be-deleted.txt
also-waste.txt
never-used-it.txt
何かを検索して、fileによって提供されるいくつかのファイルを除外するオプションを持つ削除コマンドを作成します。
rm
コマンドはコメント化されているため、必要に応じて機能していることを確認できます。次に、その行のコメントを外します。
check directory
セクションは、間違ったディレクトリから誤ってスクリプトを実行して、間違ったファイルを上書きしないようにします。
echo deleting
行を削除して、サイレントで実行できます。
#!/bin/bash
cd /home/me/myfolder2tocleanup/
# Exit if the directory isn't found.
if (($?>0)); then
echo "Can't find work dir... exiting"
exit
fi
for i in *; do
if ! grep -qxFe "$i" filelist.txt; then
echo "Deleting: $i"
# the next line is commented out. Test it. Then uncomment to removed the files
# rm "$i"
fi
done
このpythonスクリプトはこれを行うことができます:
#!/usr/bin/env python3
import os
no_remove = set()
with open('./dont-delete.txt') as f:
for line in f:
no_remove.add(line.strip())
for f in os.listdir('.'):
if f not in no_remove:
print('unlink:' + f )
#os.unlink(f)
重要な部分は、os.unlink()
関数のコメントを外すことです。
NOTE:このスクリプトとdont-delete.txt
をdont-delete.txt
に追加して、両方がリストに含まれるようにし、同じディレクトリに保管します。
ワンライナーは次のとおりです。
comm -2 -3 <(ls) <(sort dont_delete) | tail +2 | xargs -p rm
ls
は、現在のディレクトリ内のすべてのファイルを(ソート順に)印刷しますsort dont_delete
は、削除したくないすべてのファイルをソート順に出力します<()
演算子は、文字列をファイルのようなオブジェクトに変換しますcomm
コマンドは、事前にソートされた2つのファイルを比較し、それらが異なる行を出力します-2 -3
フラグを使用すると、comm
は最初のファイルに含まれる行のみを印刷し、2番目のファイルは削除しません。これは削除しても安全なファイルのリストになりますtail +2
呼び出しは、入力ファイルの名前を含むcomm
出力の見出しを削除するだけです。xargs
にパイプし、出力ストリームをrm
の引数のリストに変換します。 -p
オプションは、xargs
を実行する前に確認を求めます。FWIWは、(+cmd)
glob修飾子を使用して、zsh
でこれをネイティブに実行できるようです。
説明のために、いくつかのファイルから始めましょう
% ls
bar baz bazfoo keepfiles.txt foo kazoo
ホワイトリストファイル
% cat keepfiles.txt
foo
kazoo
bar
最初に、ホワイトリストを配列に読み込みます。
% keepfiles=( "${(f)$(< keepfiles.txt)}" )
またはおそらくより良い
% zmodload zsh/mapfile
% keepfiles=( ${(f)mapfile[./keepfiles.txt]} )
(bashのmapfile
ビルトインと同等-またはその同義語readarray
)。これで、一致するものが見つからない場合に0を返す${keepfiles[(I)filename]}
を使用して、キー(ファイル名)が配列に存在するかどうかを確認できます。
% print ${keepfiles[(I)foo]}
1
% print ${keepfiles[(I)baz]}
0
%
これを使用して、配列に$REPLY
に一致するものがない場合にtrue
を返す関数を作成できます。
% nokeep() { (( ${keepfiles[(I)$REPLY]} == 0 )); }
最後に、この関数をコマンドの修飾子として使用します。
% ls *(+nokeep)
baz bazfoo keepfiles.txt
または、あなたの場合
% rm -- *(+nokeep)
(ホワイトリストファイル自体の名前をホワイトリストに追加することをお勧めします。)
list
というファイルにリストされているファイルに空白(スペース/タブ)がないと仮定すると、次のようになります。
find /path/to -type f \( ! -name "list" $(printf ' -a ! -name %s\n' $(< list)) \)
上記のコマンドに-delete
を追加して、listファイルに存在しないファイルを削除します。検索に-delete
オプションがない場合、次のように-exec
でrm
を使用できます。
find /path/to -type f \( ! -name "list" $(printf ' -a ! -name %s\n' $(< list)) \) -exec echo rm {} \;
または -exec
ターミネータと一緒に+
を使用 .
find /path/to -type f \( ! -name "list" $(printf ' -a ! -name %s\n' $(< list)) \) -exec echo rm {} +
echo
は、ドライランにのみ使用されます。
Bashシェルのextglob
shopt
がonに設定されていると仮定すると、もう少し保守的な代替策があります。
rm !($(tr \\n \| < keep.txt))
(...付随する@gardenheadの優れたコミュニケーションの提案!)