Respuestas:
Si desea recorrer los archivos, nunca usels
*. tl; dr Hay muchas situaciones en las que terminaría borrando el archivo incorrecto, o incluso todos los archivos.
Dicho esto, desafortunadamente esto es algo complicado de hacer bien en Bash. Hay una respuesta que funciona en una pregunta duplicada incluso más antiguafind_date_sorted
que puedes usar con pequeñas modificaciones:
counter=0
while IFS= read -r -d '' -u 9
do
let ++counter
if [[ counter -gt 3 ]]
then
path="${REPLY#* }" # Remove the modification time
echo -e "$path" # Test
# rm -v -- "$path" # Uncomment when you're sure it works
fi
done 9< <(find . -mindepth 1 -type f -printf '%TY-%Tm-%TdT%TH:%TM:%TS %p\0' | sort -rz) # Find and sort by date, newest first
* No se ofendan, chicos ls
. Pero realmente no es seguro.
Editar: Nuevofind_date_sorted
con pruebas unitarias.
((++counter>3))
como prueba. Es muy sucinto. En cuanto a los oneliners: si la brevedad es una preocupación, envuelva el código en una función, entonces no se preocupe por eso.
Para eliminar todos los archivos, excepto los 3 más nuevos, utilizando un zsh glob, puede usar Om
(O mayúscula) para ordenar los archivos del más antiguo al más nuevo y un subíndice para obtener los archivos que desee.
rm ./*(Om[1,-4])
# | |||| ` stop at the 4th to the last file (leaving out the 3 newest)
# | |||` start with first file (oldest in this case)
# | ||` subscript to pick one or a range of files
# | |` look at modified time
# | ` sort in descending order
# ` start by looking at all files
Otros ejemplos:
# delete oldest file (both do the same thing)
rm ./*(Om[1])
rm ./*(om[-1])
# delete oldest two files
rm ./*(Om[1,2])
# delete everything but the oldest file
rm ./*(om[1,-2])
Con mucho, el método más fácil es usar zsh y sus calificadores globales : Om
para ordenar disminuyendo la edad (es decir, la más antigua primero) y [1,3]
retener solo las tres primeras coincidencias.
rm ./*(Om[1,3])
Vea también ¿Cómo filtro un globo en zsh para más ejemplos?
Y preste atención al consejo de l0b0 : su código se romperá horriblemente si tiene nombres de archivo que contienen caracteres especiales de shell.
Puede usar la siguiente función para obtener el archivo más nuevo en un directorio:
newest_in()
{
local newest=$1
for f;do [[ $f -nt $newest ]] && newest="$f"; done;
printf '%s\n' "$newest"
}
Dele un conjunto diferente de archivos al extraer el archivo más nuevo después de cada iteración.
Consejo: Si mantiene el conjunto inicial de archivos en una matriz llamada "$ {files [@]}", guarde el índice del archivo más nuevo encontrado y unset 'files[index]'
antes de la siguiente iteración.
Uso: newest_in [set of files/directories]
Salida de muestra:
[rany$] newest_in ./*
foo.txt
[rany$]
Primero, la -R
opción es para la recursividad, que probablemente no sea lo que desea, que también buscará en todos los subdirectorios. Segundo, el <
operador (cuando no se ve como redirección) es para la comparación de cadenas. Probablemente quieras -lt
. Tratar:
while [ `ls -1A | grep ^- | wc -l` -lt 3 ]
Pero usaría encontrar aquí:
while [ `find . -maxdepth 1 -type f -print | wc -l` -lt 3 ]
Sé que es un pecado analizar ls
, pero ¿qué pasa con esto?
find . -type f -maxdepth 1 | xargs ls -ltr | sed '1,3d' | awk '{print $9}' | xargs rm
Una prueba rápida con 5 archivos vacíos:
$ >1
$ >2
$ >3
$ >4
$ >5
$ find . -type f -maxdepth 1 | xargs ls -lt | sed '1,3d' | awk '{print $9}' | xargs rm
$ ls -1
3
4
5
ls
salida y usar find
y xargs
juntos de manera incorrecta. Si se combinan find
y xargs
te recomiendo que el uso find
s -print0
y, en consecuencia xargs
s -O
opciones. Lea sobre Uso de Buscar para obtener más información sobre el tema. También es posible que desee echar un vistazo y leer sobre por qué Analizar ls es muy malo.
Este one-liner lo hace todo lo que pienso:
ls -t1 /home/user/test | tail -n +4 | xargs -I{} rm -- "{}"
Aquí hay una solución:
rm /appserver/webapplogs/$(ls -t1 /appserver/webapplogs/|tail -1)