2012-01-19 8 views
5

¿Cómo se prueba la existencia de archivos en un directorio usando bash?sh: Prueba de existencia de archivos

if ... ; then 
    echo 'Found some!' 
fi 

Para que quede claro, no quiero para la prueba de la existencia de un archivo específico . Me gustaría probar si un directorio específico contiene cualquier archivo.


Fui con:

(
    shopt -s dotglob nullglob 
    existing_files=(./*) 
    if [[ ${#existing_files[@]} -gt 0 ]] ; then 
     some_command "${existing_files[@]}" 
    fi 
) 

Utilizando la matriz evita las condiciones de carrera a partir de la lectura de la lista de archivos dos veces.

+0

¿Qué pasa si el directorio contiene subdirectorios, pero no hay archivos ordinarios? –

+0

@ Keith Thompson, No va a suceder. – ikegami

+0

posible duplicado de [Comprobación de si un directorio contiene archivos] (http://stackoverflow.com/questions/91368/checking-if-a-directory-contains-files) –

Respuesta

7

Normalmente solo uso un ls barato -A para ver si t aquí hay una respuesta.

Pseudo-quizás-correcta-sintaxis de ejemplo-ahoy:

if [[ $(ls -A my_directory_path_variable) ]] then.... 

edición, esto va a funcionar:

myDir=(./*) if [ ${#myDir[@]} -gt 1 ]; then echo "there's something down here"; fi

+0

Esta respuesta debería funcionar para usted, incluso si es algo hackish. Voy a apuñalar una solución de todo sh/bash. –

+0

Se siente un poco retorcido, pero de hecho funciona. Espero ver lo que se te ocurra :) – ikegami

+1

myDir = (./*) if [$ {# myDir [@]} -gt 1]; luego echo "hay algo aquí abajo"; fi ... aquí tienes. conecta y reproduce. –

9

Desde la página del manual:

-f file 
      True if file exists and is a regular file. 

Así:

if [ -f someFileName ]; then echo 'Found some!'; fi 

Editar: Veo que ya tiene la respuesta, pero está completo, se puede utilizar la información en Checking from shell script if a directory contains files - y perder la opción dotglob si desea que se ignoren los archivos ocultos.

+0

Eso prueba la existencia de un archivo específico. Me gustaría probar la existencia de cualquier archivo. – ikegami

+0

Ah, he entendido mal. De acuerdo, ¿necesita capturar archivos ocultos (es decir, .xyz)? –

+0

No, ignorar los archivos ocultos está bien. – ikegami

3

Prueba este

if [ -f /tmp/foo.txt ] 
then 
    echo the file exists 
fi 

ref: http://tldp.org/LDP/abs/html/fto.html

posible que también desee comprobar esto: http://tldp.org/LDP/abs/html/fto.html

¿Qué tal esto para si el directorio está vacío o no

$ find "/tmp" -type f -exec echo Found file {} \; 
+0

Eso prueba la existencia de un archivo específico. Me gustaría probar la existencia de cualquier archivo. – ikegami

1
#!/bin/bash 

if [ -e $1 ]; then 
     echo "File exists" 
else 
     echo "Files does not exist" 
fi 
+0

Eso prueba la existencia de un archivo específico. Me gustaría probar la existencia de cualquier archivo en un directorio específico. – ikegami

3

Usted puede utilizar ls en un comunicado por if tanto :

if [[ "$(ls -a1 | egrep -v '^\.$|^\.\.$')" = "" ]] ; then echo empty ; fi 

o, gracias a Ikegami,

if [[ "$(ls -A)" = "" ]] ; then echo empty ; fi 

o, aún más corto:

if [[ -z "$(ls -A)" ]] ; then echo empty ; fi 

Estos básicamente una lista de todos los archivos en el directorio actual (incluyendo los ocultos) que no son ni . ni ...

Si esa lista está vacía, entonces el directorio está vacío.

Si desea descartar los archivos ocultos, puede simplificar a:

if [[ "$(ls)" = "" ]] ; then echo empty ; fi 

Una solución -sólo bash (no hay programas externos que invocan como ls o egrep) se puede hacer de la siguiente manera:

emp=Y; for i in *; do if [[ $i != "*" ]]; then emp=N; break; fi; done; echo $emp 

no es el más bonito código en el mundo, sino que simplemente establece emp a Y y luego, para cada archivo real, lo establece en N y se rompe el ciclo for por eficiencia. Si hubo cero archivos, permanece como Y.

+0

Si 's/ls -a/ls -A /', la necesidad del 'egrep' desaparece. – ikegami

+0

¿Por qué usar egrep cuando puedes permanecer dentro de bash? Además, no es necesario comparar el resultado con una cadena vacía. esto es más caro de lo que necesita ser. –

+0

@tristan, esa es probablemente la razón por la que obtuviste la aceptación en lugar de mí :-) Sin embargo, debes tener en cuenta que ninguna de mis soluciones anteriores, no tuya, se mantiene "dentro de bash". Todos invocan 'ls' y ejecutable externo. Agregaré una solución solo de bash, aunque será fea. – paxdiablo

1

no tengo una buena solución sh/bash pura, pero es fácil de hacer en Perl:

#!/usr/bin/perl 

use strict; 
use warnings; 

die "Usage: $0 dir\n" if scalar @ARGV != 1 or not -d $ARGV[0]; 
opendir my $DIR, $ARGV[0] or die "$ARGV[0]: $!\n"; 
my @files = readdir $DIR; 
closedir $DIR; 
if (scalar @files == 2) { # . and .. 
    exit 0; 
} 
else { 
    exit 1; 
} 

llamada algo así como emptydir y ponerlo en algún lugar de su $PATH, entonces:

if emptydir dir ; then 
    echo "dir is empty" 
else 
    echo "dir is not empty" 
fi 

Muere con un mensaje de error si no le da argumentos, dos o más argumentos, o un argumento que no es un directorio; es bastante fácil cambiar si prefieres un comportamiento diferente.

+1

'exit (definido (glob quotemeta ($ ARGV [0] //". ")."/* ")? 0: 1)' – ikegami

+0

oh correcto, el mío no comprueba si hay archivos ocultos. – ikegami

0

Para la diversión:

if (shopt -s nullglob ; perl -e'exit [email protected]' ./*) ; then 
    echo 'Found some!' 
fi 

(no comprueba los archivos ocultos)

1
# tested on Linux BASH 

directory=$1 

if test $(stat -c %h $directory) -gt 2; 
then 
    echo "not empty" 
else 
    echo "empty" 
fi 
+0

Puede obtener un falso negativo en los directorios raíz, pero genial. – ikegami

Cuestiones relacionadas