「ls」(奇妙な名前のファイル) で問題のない解決策
これは、ceving と anubhava の答えを組み合わせたものです。両方の解決策がうまくいきません。アーカイブ内のファイルをバックアップするために毎日実行する必要があるスクリプトを探していたので、 ls
の問題を回避したかった (誰かが変な名前のファイルを私のバックアップ フォルダに保存した可能性があります)。そこで、前述のソリューションをニーズに合わせて修正しました。
私のソリューションは、例外を除くすべてのファイルを削除します 3 つの最新ファイル。
find . -type f -printf '%[email protected]\t%p\n' |
sort -t $'\t' -g |
head -n -3 |
cut -d $'\t' -f 2- |
xargs rm
いくつかの説明:
find
現在のフォルダー内のすべてのファイル (ディレクトリではない) を一覧表示します。それらはタイムスタンプ付きで出力されます。
sort
タイムスタンプに基づいて行を並べ替えます (古いものが上になります)。
head
先頭行から最後の 3 行までを出力します。
cut
タイムスタンプを削除します。
xargs
rm
を実行します
私の解決策を確認してください:
(
touch -d "6 days ago" test_6_days_old
touch -d "7 days ago" test_7_days_old
touch -d "8 days ago" test_8_days_old
touch -d "9 days ago" test_9_days_old
touch -d "10 days ago" test_10_days_old
)
これにより、現在のフォルダーに異なるタイムスタンプを持つ 5 つのファイルが作成されます。最初にこのスクリプトを実行してから、古いファイルを削除するコードを実行してください。
これにより、最新の 3 つを除くすべてのファイルが一覧表示されます:
ls -t | tail -n +4
これにより、これらのファイルが削除されます:
ls -t | tail -n +4 | xargs rm --
これにより、ドットファイルもリストされます:
ls -At | tail -n +4
ドットファイルで削除:
ls -At | tail -n +4 | xargs rm --
ただし、注意してください:ls
の解析 ファイル名に改行やスペースなどの変な文字が含まれている場合、危険な場合があります。ファイル名に変な文字が含まれていないことが確実な場合は、 ls
を解析します 1 回限りのスクリプトであればなおさらです。
繰り返し使用するスクリプトを開発している場合は、ls
の出力を解析しないでください。 ここで説明されている方法を使用します:http://mywiki.wooledge.org/ParsingLs
ls -t | tail -n +4 | xargs -I {} rm {}
1ライナーをご希望の場合
以下は少し複雑に見えますが、通常とは異なる、または意図的に悪意のあるファイル名であっても、正確であるように十分注意してください。残念ながら、GNU ツールが必要です:
count=0
while IFS= read -r -d ' ' && IFS= read -r -d '' filename; do
(( ++count > 3 )) && printf '%s\0' "$filename"
done < <(find . -maxdepth 1 -type f -printf '%[email protected] %P\0' | sort -g -z) \
| xargs -0 rm -f --
これがどのように機能するかを説明します:
- Find は
<mtime> <filename><NUL>
を出力します 現在のディレクトリ内の各ファイルに対して。 sort -g -z
行が NUL で区切られた最初の列 (時間) に基づいて、一般的な (整数ではなく浮動小数点) 数値ソートを行います。- 最初の
read
while
で ループは mtime を取り除きます (sort
以降は不要です) - 2 番目の
read
while
で ループはファイル名を読み取ります (NUL まで実行)。 - ループはカウンタをインクリメントしてからチェックします。カウンタの状態が最初のスキップを過ぎたことを示している場合、NUL で区切られたファイル名を出力します。
xargs -0
次に、そのファイル名を収集中の argv リストに追加してrm
を呼び出します