¿Cómo haría para saber si los archivos de una extensión específica están presentes en un directorio, con bash?
Algo como
if [ -e *.flac ]; then
echo true;
fi
#!/bin/bash
count=`ls -1 *.flac 2>/dev/null | wc -l`
if [ $count != 0 ]
then
echo true
fi
ls -l
, mi respuesta usals -1
ls -1
se imprimirá una línea por archivo\n
(y sí, eso es válido en los nombres de archivo).#/bin/bash myarray=(`find ./ -maxdepth 1 -name "*.py"`) if [ ${#myarray[@]} -gt 0 ]; then echo true else echo false fi
fuente
${#myarray[@]}
igual a 1ls -1 *.py
lugar de buscarEsto usa ls (1), si no existen archivos flac, ls informa de un error y se cierra el script; De lo contrario, el script continúa y los archivos pueden ser procesados.
#! /bin/sh ls *.flac >/dev/null || exit ## Do something with flac files here
fuente
if ls *.flac >/dev/null 2>&1; then ... fi;
shopt -s nullglob if [[ -n $(echo *.flac) ]] # or [ -n "$(echo *.flac)" ] then echo true fi
fuente
Debe tener cuidado con qué bandera coloca en su
if
declaración y cómo se relaciona con el resultado que desea.Si desea verificar solo archivos normales y no otros tipos de entradas del sistema de archivos, entonces querrá cambiar el esqueleto de su código a:
if [ -f file ]; then echo true; fi
El uso de la
-f
restringeif
a archivos normales, mientras que-e
es más expansivo y coincidirá con todos los tipos de entradas del sistema de archivos. Por supuesto, hay otras opciones como-d
directorios, etc. Consulte http://tldp.org/LDP/abs/html/fto.html para obtener una buena lista.Como lo señaló @msw,
test
(es decir[
) se ahogará si intenta alimentarlo con más de un argumento. Esto podría suceder en su caso si el glob para*.flac
devolvió más de un archivo. En ese caso, intente envolver suif
prueba en un bucle como:for file in ./*.pdf do if [ -f "${file}" ]; then echo 'true'; break fi done
De esta manera,
break
en la primera instancia de la extensión de archivo que desea y puede continuar con el resto del script.fuente
test
(también conocido como[
) se queja si el patrón se expande a más de un archivo: "operador binario esperado" o "demasiados argumentos""$file"
, porque el nombre del archivo puede contener algunos caracteres incorrectos, como espacios o asteriscos.#!/bin/bash files=$(ls /home/somedir/*.flac 2> /dev/null | wc -l) if [ "$files" != "0" ] then echo "Some files exists." else echo "No files with that extension." fi
fuente
La mejor solución
(if [ -e *.flac ];)
no funcionó para mí, dando:[: too many arguments
if ls *.flac >/dev/null 2>&1;
entonces funcionará.fuente
Puede usar -f para verificar si existen archivos de un tipo específico:
#!/bin/bash if [ -f *.flac ] ; then echo true fi
fuente
[
(a diferencia de la más común[[
) no evita el globbing.shopt -s nullglob set -- $(echo *.ext) if [ "${#}" -gt 0 ];then echo "got file" fi
fuente
-ge
lugar de-gt
, porque de lo contrario su código no detectará el archivo único. En segundo lugar, si no hay archivos que coincidan con el patrón, cualquier shell conforme dejará la cadena*.ext
intacta, por lo que aún obtendrá un "resultado".bash solo:
any_with_ext () ( ext="$1" any=false shopt -s nullglob for f in *."$ext"; do any=true break done echo $any ) if $( any_with_ext flac ); then echo "have some flac" else echo "dir is flac-free" fi
Utilizo paréntesis en lugar de llaves para asegurarme de que se usa una subcapa (no quiero golpear su
nullglob
configuración actual ).fuente
Aquí hay una solución que no usa comandos externos (es decir, no
ls
), sino una función de shell. Probado en bash:shopt -s nullglob function have_any() { [ $# -gt 0 ] } if have_any ./*.flac; then echo true fi
La función
have_any
utiliza$#
para contar sus argumentos y[ $# -gt 0 ]
luego prueba si hay al menos un argumento. El uso de en./*.flac
lugar de solo*.flac
en la llamada ahave_any
es para evitar problemas causados por archivos con nombres como--help
.fuente
Para completar, con zsh:
if [[ -n *.flac(#qN) ]]; then echo true fi
Esto se enumera al final de la sección Expresiones condicionales en el manual de zsh. Dado que
[[
deshabilita el globbing de nombre de archivo, necesitamos forzar la generación del nombre de archivo usando(#q)
al final de la cadena de globbing, luego laN
bandera (NULL_GLOB
opción) para forzar que la cadena generada esté vacía en caso de que no haya coincidencia.fuente
Aquí tienes una solución bastante simple:
if [ "$(ls -A | grep -i \\.flac\$)" ]; then echo true; fi
Como puede ver, esta es solo una línea de código, pero funciona bastante bien. Debería funcionar tanto con bash como con un shell compatible con posix como dash. Tampoco distingue entre mayúsculas y minúsculas y no le importa qué tipo de archivos (regulares, enlace simbólico, directorio, etc.) estén presentes, lo que podría ser útil si tiene algunos enlaces simbólicos o algo así.
fuente
Probé esto:
if [ -f *.html ]; then echo "html files exist" else echo "html files dont exist" fi
Usé este código sin ningún problema para otros archivos, pero para los archivos html recibí un error :
Luego probé la solución de conteo de @ JeremyWeir, que funcionó para mí.
Tenga en cuenta que tendrá que restablecer el recuento si está haciendo esto en un bucle:
count=$((0))
fuente
Esto debería funcionar en cualquier shell similar a borne que existe:
if [ "$(find . -maxdepth 1 -type f | grep -i '.*\.flac$')" ]; then echo true fi
Esto también funciona con GNU
find
, pero IDK si es compatible con otras implementaciones defind
:if [ "$(find . -maxdepth 1 -type f -iname \*.flac)" ]; then echo true fi
fuente