¿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
Respuestas:
#!/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
${#myarray[@]}
igual a 1
ls -1 *.py
lugar de buscar
Esto 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
if ls *.flac >/dev/null 2>&1; then ... fi;
shopt -s nullglob
if [[ -n $(echo *.flac) ]] # or [ -n "$(echo *.flac)" ]
then
echo true
fi
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
restringe if
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 su if
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.
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.
La mejor solución (if [ -e *.flac ];)
no funcionó para mí, dando:[: too many arguments
if ls *.flac >/dev/null 2>&1;
entonces funcionará.
Puede usar -f para verificar si existen archivos de un tipo específico:
#!/bin/bash
if [ -f *.flac ] ; then
echo true
fi
[
(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
-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 ).
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 a have_any
es para evitar problemas causados por archivos con nombres como --help
.
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 la N
bandera ( NULL_GLOB
opción) para forzar que la cadena generada esté vacía en caso de que no haya coincidencia.
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í.
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 :
[: too many arguments
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))
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 de find
:
if [ "$(find . -maxdepth 1 -type f -iname \*.flac)" ]; then
echo true
fi