whileループはすべてのファイルを削除し、ループに閉じ込められます。

whileループはすべてのファイルを削除し、ループに閉じ込められます。

特定の数のファイルが残るまで、ファイルを削除するために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削除されたファイルごとに一度呼び出すことを防ぎます。

このコードは、名前(最後に変更されたタイムスタンプではありません)に基づいてファイルを削除します。これはあなたのコードでもやりたいことのようです。

おすすめ記事