特定の数のファイルが残るまで、ファイルを削除するためにwhileループを使用することはできません。
これが私が持っているものです:
touch while/151234
touch while/152355
touch while/151694
touch while/153699
touch while/156946
NUMSNAPS=$(ls while | awk '{print $1}' | wc -l)
RETAIN=2
while [ "$RETAIN" -le "$NUMSNAPS" ]; do
OLDEST=$(ls | awk '{print $1}' | head -n 1)
rm "$OLDEST"
done
実際には他のサードパーティのコマンドで使用されるテストなので、findを使用してこれらのファイルを削除することはできません。 DOCTLを使用してスナップショットを見つけ、1つが残るまで削除する予定です。
ベストアンサー1
絶対に変更しない2つの変数に基づいて特定の条件をテストするループがあります。NUMSNAPS
各反復ごとに値を1ずつ減らすことを意味するとします。
zsh
シェルではできます
retain=2
rm -f while/*(DN.Om[retain+1,-1])
$retain
最近変更されたファイルを除くすべての一般的なファイル(隠された名前のファイルを含む)を削除します。何千ものファイルが発生した場合は、次のものを使用できますzargs
。
retain=2
autoload -U zargs
zargs -- while/*(DN.Om[retain+1,-1]) -- rm
ファイルを名前でソートするにはOm
(「Mtimeタイムスタンプで降順を並べ替える」)をOn
(「名前で降順に並べ替える」)に置き換えます。
zsh
明らかに、たとえば使用する代わりに他のシェルから呼び出すことができます。
retain=2
zsh -c 'rm -f $2/*(DN.Om[$1+1,-1])' zsh "$retain" "while"
これにより、インラインスクリプトに保持するディレクトリ名とファイル数も渡されるため、既存の非スクリプトに簡単にマージできますzsh
。
シェルではbash
本当に欲しくない出力の解析ls
。代わりに、以下を使用したい場合があります。
shopt -s dotglob nullglob
retain=2
set -- while/*
while [ "$#" -gt "$retain" ]; do
rm -f "$1"
shift
done
これは、場所引数リストをwhile
ディレクトリのファイルリスト(隠し名前を含む)に設定し、リストにファイルのみが残るretain
までそのリストからファイルを削除します。
これにより、厄介なファイル名の問題を回避し、ls
削除されたファイルごとに一度呼び出すことを防ぎます。
このコードは、名前(最後に変更されたタイムスタンプではありません)に基づいてファイルを削除します。これはあなたのコードでもやりたいことのようです。