Necesitaba una solución elegante para el busybox (enrutador), todas las soluciones de xargs o array me resultaron inútiles; no hay tal comando disponible allí. find and mtime no es la respuesta adecuada, ya que estamos hablando de 10 elementos y no necesariamente de 10 días. La respuesta de Espo fue la más corta, más limpia y probablemente la más irreversible.
Los errores con espacios y cuando no se van a eliminar archivos se resuelven simplemente de la manera estándar:
rm "$(ls -td *.tar | awk 'NR>7')" 2>&-
Versión un poco más educativa: podemos hacerlo todo si usamos awk de manera diferente. Normalmente, uso este método para pasar (devolver) variables del awk al sh. Como leemos todo el tiempo que no se puede hacer, ruego diferir: aquí está el método.
Ejemplo para archivos .tar sin problemas con respecto a los espacios en el nombre del archivo. Para probar, reemplace "rm" con el "ls".
eval $(ls -td *.tar | awk 'NR>7 { print "rm \"" $0 "\""}')
Explicación:
ls -td *.tar
enumera todos los archivos .tar ordenados por hora. Para aplicar a todos los archivos en la carpeta actual, elimine la parte "d * .tar"
awk 'NR>7...
salta las primeras 7 líneas
print "rm \"" $0 "\""
construye una línea: rm "nombre de archivo"
eval
lo ejecuta
Como estamos usando rm
, ¡no usaría el comando anterior en un script! El uso más sabio es:
(cd /FolderToDeleteWithin && eval $(ls -td *.tar | awk 'NR>7 { print "rm \"" $0 "\""}'))
En el caso de usar el ls -t
comando no hará ningún daño en ejemplos tan tontos como: touch 'foo " bar'
ytouch 'hello * world'
. ¡No es que alguna vez creamos archivos con tales nombres en la vida real!
Nota al margen. Si quisiéramos pasar una variable al sh de esta manera, simplemente modificaríamos la impresión (forma simple, sin espacios tolerados):
print "VarName="$1
para establecer la variable VarName
al valor de $1
. Se pueden crear múltiples variables de una vez. Esto se VarName
convierte en una variable sh normal y se puede usar normalmente en un script o shell después. Entonces, para crear variables con awk y devolverlas al shell:
eval $(ls -td *.tar | awk 'NR>7 { print "VarName=\""$1"\"" }'); echo "$VarName"
ls
está en el directorio actual, las rutas a los archivos contendrán '/', lo que significa quegrep -v '/'
no coincidirán con nada. Creo quegrep -v '/$'
es lo que desea excluir solo directorios.grep
comando sea conceptualmente más claro. Sin embargo, tenga en cuenta que el problema que describe no habría surgido con una sola ruta de directorio; por ejemplo,ls -p /private/var
solo imprimiría simples nombres de archivo. Solo si pasa varios argumentos de archivo (generalmente a través de un globo) vería rutas reales en la salida; por ejemplo,ls -p /private/var/*
(y también verá el contenido de los subdirectorios coincidentes, a menos que también lo haya incluido-d
).