2010-07-02 19 views
12

Tengo una carpeta con copias de seguridad de una base de datos MySQL que se crean automáticamente. Su nombre se compone de la fecha en que se hizo la copia de seguridad, así:Script de shell: obtenga el nombre del último archivo en una carpeta por orden alfabético

2010-06-12_19-45-05.mysql.gz 
2010-06-14_19-45-05.mysql.gz 
2010-06-18_19-45-05.mysql.gz 
2010-07-01_19-45-05.mysql.gz 

¿Qué es una manera de obtener el nombre de archivo del último archivo de la lista, es decir, de la que por orden alfabético ocupa el último lugar?

En un script de shell, me gustaría hacer algo como

LAST_BACKUP_FILE= ??? 
gunzip $LAST_BACKUP_FILE; 

Respuesta

17
ls -1 | tail -n 1 

Si desea asignar a un variable, utilice $(...) o invertidas.

FILE=`ls -1 | tail -n 1` 
FILE=$(ls -1 | tail -n 1) 
+0

¡Guau, eso fue rápido! Y funciona como un encanto. ¡Gracias! – yan

+0

¿Cómo limitaría los archivos ls a .gz solo en una ruta fija? (Como: El último archivo con la extensión .gz en la carpeta/home/xy/abc) – yan

+0

Al igual que usas 'ls' normalmente, algo así como' ls -1/home/xy/abc/*. Gz'. – Sjoerd

6

@ respuesta de Sjoerd es correcta, sólo voy a recoger unas cuantas liendres de ella:

  1. que no necesitan la opción -1 para hacer cumplir una ruta por línea si canalizar la salida en alguna parte:

    ls | tail -n 1 
    
  2. puede utilizar -r para obtener la lista en orden inverso, y tomar la primera de ellas:

    ls -r | head -n 1 
    
  3. gunzip some.log.gz escribirá datos sin comprimir en some.log y quitar some.log.gz, que puede o no puede ser lo que quiere (probablemente no lo es). Si desea mantener el origen comprimido, tubería en gunzip:

    gunzip < some.file.gz 
    
  4. es posible que desee proteger la secuencia de comandos en la situación cuando el directorio contiene archivos, ya

    gunzip $empty_variable 
    

se expande solo

gunzip 

y dicha invocación esperará indefinidamente para los datos en la entrada estándar:

latest="$(ls -r /some/where/*.gz | head -1)" 
    if test -z "$latest"; then 
     # there's no logs yet, bail out 
     exit 
    fi 
    gunzip < $latest 
+0

(1) Sí; (2) Sip; (3) o '' gzip -cd some.file.gz> some.file' 'deja el archivo comprimido original; (4) Sí, compruebe los resultados antes de usarlos. –

2

La carcasa es más poderosa de lo que muchos piensan. Solo deja que funcione para ti. Suponiendo nombres de archivo sin espacios,

set -- $(ls -r *.gz) 
LAST_BACKUP_FILE=$1 

hace el truco con un solo tenedor, no hay tuberías, e incluso se puede evitar el tenedor si su shell soporta expansión aritmética como en

set -- *.gz 
shift $(($# - 1)) 
LAST_BACKUP_FILE=$1 
4

ls puede producir resultados inesperados cuando otros comandos lo analicen si los nombres de archivo tienen caracteres inusuales.El siguiente siempre funciona:

for LAST_BACKUP_FILE in *; do : ; done 

for LAST_BACKUP_FILE in * bucles a través de cada nombre de archivo en el orden en el directorio actual, almacenando cada uno en $LAST_BACKUP_FILE

do : no hace nada

done acabados después de que el último archivo

Ahora , el último archivo se almacena en $LAST_BACKUP_FILE.

Si por casualidad usted quiere que el primer archivo, utilice esto:

for FIRST_BACKUP_FILE in *; do break; done 

La declaración break salta fuera del circuito después del primer archivo se almacena en $FIRST_BACKUPT_FILE.

+1

Esta es la única respuesta en este hilo que no es suicida. [Nunca debería analizar el resultado de 'ls'] (http://unix.stackexchange.com/questions/128985/why-not-parse-ls). – Alex

Cuestiones relacionadas