GNU/Linux >> Tutoriales Linux >  >> Linux

¿Probar si hay archivos que coincidan con un patrón para ejecutar un script?

Estoy tratando de escribir un if declaración para probar si hay archivos que coincidan con un determinado patrón. Si hay un archivo de texto en un directorio, debe ejecutar un script determinado.

Mi código actualmente:

if [ -f /*.txt ]; then ./script fi

Por favor dé algunas ideas; Solo quiero ejecutar el script si hay un .txt en el directorio.

Respuesta aceptada:

[ -f /*.txt ]

devolvería verdadero solo si hay uno (y solo uno) archivo no oculto en / cuyo nombre termina en .txt y si ese archivo es un archivo normal o un enlace simbólico a un archivo normal.

Esto se debe a que el shell expande los comodines antes de pasarlos al comando (aquí [ ).

Entonces, si hay un /a.txt y /b.txt , [ se le pasarán 5 argumentos:[ , -f , /a.txt , /b.txt y ] . [ luego se quejaría de que -f recibe demasiados argumentos.

Si desea comprobar que el *.txt el patrón se expande a al menos un archivo no oculto (regular o no), en el bash concha:

shopt -s nullglob
set -- *.txt
if [ "$#" -gt 0 ]; then
  ./script "[email protected]" # call script with that list of files.
fi
# Or with bash arrays so you can keep the arguments:
files=( *.txt )
# apply C-style boolean on member count
(( ${#files[@]} )) && ./script "${files[@]}"

shopt -s nullglob es bash específico (shopt es, nullglob en realidad proviene de zsh ), pero shells como ksh93 , zsh , yash , tcsh tienen declaraciones equivalentes.

Con zsh , la prueba para hay archivos que coincidan con un patrón se puede escribir usando una función anónima y el N (para nullglob ) y Y1 (para detenerse después de la primera búsqueda) calificador global:

if ()(($#)) *.txt(NY1); then
  do-something
fi

Tenga en cuenta que esos encuentran esos archivos leyendo el contenido del directorio, no intenta acceder a esos archivos en absoluto, lo que lo hace más eficiente que las soluciones que llaman a comandos como ls o stat en esa lista de archivos calculados por el shell.

El estándar sh equivalente sería:

set -- [*].txt *.txt
case "$1$2" in
  ('[*].txt*.txt') ;;
  (*) shift; script "[email protected]"
esac

El problema es que con los shells Bourne o POSIX, si un patrón no coincide, se expande a sí mismo. Entonces si *.txt se expande a *.txt , no sabes si es porque no hay .txt archivo en el directorio o porque hay un archivo llamado *.txt . Usando [*].txt *.txt permite discriminar entre los dos.

Ahora, si quieres comprobar que el *.txt coincide con al menos un regular archivo o enlace simbólico a un archivo normal (como su [ -f *.txt ] sugiere que desea hacer), o que todos los archivos que coincidan con *.txt son normales archivos (después de la resolución del enlace simbólico), eso es otro asunto.

Relacionado:¿Cómo generar un script de creación de tabla sin clave principal y externa en Oracle?

Con zsh :

if ()(($#)) *.txt(NY1-.); then
  echo "there is at least one regular .txt file"
fi
if ()(($#)) *.txt(NY1^-.); then
  echo "there is at least one non-regular .txt files"
fi

(quitar el - si desea realizar la prueba antes de la resolución del enlace simbólico, es decir, considere los enlaces simbólicos como archivos no regulares, ya sea que apunten a archivos regulares o no).


Linux
  1. ¿Es posible averiguar qué programa o secuencia de comandos creó un archivo determinado?

  2. ¿Archivos Cat con directorio?

  3. ¿Reemplazar líneas que coinciden con un patrón con líneas de otro archivo en orden?

  4. ¿Script para determinar si los archivos son imágenes?

  5. Cómo probar un script PHP

Ejecutar archivos binarios en Linux

Encuentre y elimine el archivo más antiguo si hay más de X archivos en un directorio en Linux

Verifique que haya al menos dos argumentos dados en un script bash

¿Hay algún programa/script para modificar archivos .conf?

Copie todos los archivos que coincidan con el patrón del directorio y los subdirectorios en un solo directorio

¿Cómo usar el comando de búsqueda para eliminar archivos que coincidan con un patrón?