¿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 -1ls -1se 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 fifuente
${#myarray[@]}igual a 1ls -1 *.pylugar 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 herefuente
if ls *.flac >/dev/null 2>&1; then ... fi;shopt -s nullglob if [[ -n $(echo *.flac) ]] # or [ -n "$(echo *.flac)" ] then echo true fifuente
Debe tener cuidado con qué bandera coloca en su
ifdeclaració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; fiEl uso de la
-frestringeifa archivos normales, mientras que-ees más expansivo y coincidirá con todos los tipos de entradas del sistema de archivos. Por supuesto, hay otras opciones como-ddirectorios, 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*.flacdevolvió más de un archivo. En ese caso, intente envolver suifprueba en un bucle como:for file in ./*.pdf do if [ -f "${file}" ]; then echo 'true'; break fi doneDe esta manera,
breaken 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." fifuente
La mejor solución
(if [ -e *.flac ];)no funcionó para mí, dando:[: too many argumentsif 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 fifuente
[(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" fifuente
-gelugar 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*.extintacta, 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" fiUtilizo paréntesis en lugar de llaves para asegurarme de que se usa una subcapa (no quiero golpear su
nullglobconfiguració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 fiLa función
have_anyutiliza$#para contar sus argumentos y[ $# -gt 0 ]luego prueba si hay al menos un argumento. El uso de en./*.flaclugar de solo*.flacen la llamada ahave_anyes para evitar problemas causados por archivos con nombres como--help.fuente
Para completar, con zsh:
if [[ -n *.flac(#qN) ]]; then echo true fiEsto 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 laNbandera (NULL_GLOBopció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; fiComo 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" fiUsé 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 fiEsto 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 fifuente