Řešení bez problémů s "ls" (divně pojmenované soubory)
Toto je kombinace cevingovy a anubhavovy odpovědi. Obě řešení pro mě nefungují. Protože jsem hledal skript, který by se měl spouštět každý den pro zálohování souborů v archivu, chtěl jsem se vyhnout problémům s ls
(někdo mohl uložit nějaký vtipný pojmenovaný soubor do mé záložní složky). Zmíněná řešení jsem tedy upravil tak, aby vyhovovala mým potřebám.
Moje řešení odstraní všechny soubory, kromě tři nejnovější soubory.
find . -type f -printf '%[email protected]\t%p\n' |
sort -t $'\t' -g |
head -n -3 |
cut -d $'\t' -f 2- |
xargs rm
Nějaké vysvětlení:
find
vypíše všechny soubory (ne adresáře) v aktuální složce. Jsou vytištěny s časovými razítky.
sort
seřadí řádky podle časového razítka (nejstarší nahoře).
head
vytiskne horní řádky až po poslední 3 řádky.
cut
odstraní časová razítka.
xargs
běží rm
pro každý vybraný soubor.
Pro ověření mého řešení:
(
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
)
Tím se v aktuální složce vytvoří 5 souborů s různými časovými razítky. Nejprve spusťte tento skript a poté kód pro mazání starých souborů.
Zobrazí se seznam všech souborů kromě nejnovějších tří:
ls -t | tail -n +4
Tímto smažete tyto soubory:
ls -t | tail -n +4 | xargs rm --
Zobrazí se také seznam dotfiles:
ls -At | tail -n +4
a odstranit pomocí dotfiles:
ls -At | tail -n +4 | xargs rm --
Ale pozor:parsování ls
může být nebezpečné, pokud názvy souborů obsahují zábavné znaky, jako jsou nové řádky nebo mezery. Pokud jste si jisti, že vaše názvy souborů neobsahují vtipné znaky, analyzujte ls
je docela bezpečný, o to více, pokud jde o jednorázový skript.
Pokud vyvíjíte skript pro opakované použití, pak byste určitě neměli analyzovat výstup ls
a použijte metody popsané zde:http://mywiki.wooledge.org/ParsingLs
ls -t | tail -n +4 | xargs -I {} rm {}
Pokud chcete 1 vložku
Následující vypadá trochu komplikovaně, ale je velmi opatrné, aby bylo správné, a to i v případě neobvyklých nebo úmyslně škodlivých názvů souborů. Bohužel to vyžaduje nástroje 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 --
Vysvětlení, jak to funguje:
- Najít vysílá
<mtime> <filename><NUL>
pro každý soubor v aktuálním adresáři. sort -g -z
provádí obecné (s plovoucí desetinnou čárkou, na rozdíl od celého čísla) číselné řazení na základě prvního sloupce (časů) s řádky oddělenými hodnotami NUL.- Prvních
read
vwhile
smyčka odstraní mtime (posort
již není potřeba je hotovo). - Druhý
read
vwhile
smyčka přečte název souboru (běží až do NUL). - Smyčka zvyšuje a poté kontroluje čítač; pokud stav počítadla ukazuje, že jsme minuli počáteční přeskočení, vytiskneme název souboru oddělený hodnotou NUL.
xargs -0
pak tento název souboru připojí do seznamu argv, který shromažďuje, aby vyvolalrm
s.