string - Cómo hacer que el script bash verifique si hay letras mayúsculas consecutivas

CorePress2024-01-24  10

Tengo una carpeta con un montón de archivos JPEG y quiero verificar si sus nombres de archivo cumplen con mis criterios de nombre de archivo: (1) sin espacios, (2) sin guiones bajos, (3) sin letras mayúsculas consecutivas, (4) y cada El nombre del archivo debe terminar en "-original.jpg". Envío cualquier nombre de archivo incorrecto y luego le solicito al usuario que continúe o no. Mi siguiente script funciona muy bien para las condiciones (1), (2) y (4), pero quiero agregar la condición (3) como otra otra opción.

i=0  # Initialize issue counter

# Detect and indicate any filename issues
for file in *.jpg; do
    if [[ $file = *" "* ]] | [[ $file = *"_"* ]]
        then
        echo "Filename issue: " $file
        i=$((i+1))
    elif [[ $file != *"-original.jpg" ]] 
        then
        echo "Filename issue: " $file
        i=$((i+1))
    fi
done

# If condition satisfied, provide indication of no filename issues
if [[ $i == 0 ]]
then
  echo "No filename issues"
fi
echo

# Prompt user if they want to continue with image processing
read -p "Proceed with image processing? (enter 'y' or 'n') " yn
case $yn in
  [Yy]* ) 
    echo 
    echo "PROCEED"
    echo
    break;;
  [Nn]* ) echo; exit;;
   * ) echo "Please answer yes or no. ";;
esac

Pude improvisar esto para la condición (3) y detecta mayúsculas consecutivas, pero no puedo entender cómo hacer que genere la cadena más grande ($nombre) que está analizando y/o pasarle una variable el script de shell más grande. ¿Cuál es la mejor manera de hacer esto?

echo "$name" | 
awk '{
   for (i=2; i<=NF; i++) {
      if ($i ~ /[A-Z]/ && $(i+1) ~ /[A-Z]/) {
         echo "capitalization problem"
      }
      echo "no capitalization problem"
   }
}' 


------------------------------------

Utilice la coincidencia de patrones de expresiones regulares proporcionada por bash usando =~ dentro de [[ ]]

if [[ $name =~ [[:upper:]]{2} ]]; then
  printf 'Capitalize problem!\n'
else
  prinf 'No capitalize problem.\n'
fi

Como lo mencionó @shawn, actualizado a [[:upper:]]{2}

3

1

Para "sin letras mayúsculas consecutivas", ¿no sería [[:upper:]]+? (o [[:upper:]][[:upper:]] usando BRE)

- David C. Rankin

2 de marzo7, 2021 a las 2:38

@DavidC.Rankin, gracias por ese maravilloso comentario. Se actualizó la respuesta.

- Jetchisel

27 de marzo de 2021 a las 2:43

1

[[:upper:]]+ coincidirá con cualquier letra mayúscula. [[:upper:]]{2} para dos mayúsculas consecutivas.

-Shawn

27/03/2021 a las 8:02



------------------------------------

Puedes utilizar un canal grep simple para comprobar si hay caracteres mayúsculos conestivos, algo así como

pax:/> if echo aBbd | grep '[A-Z][A-Z]' >/dev/null ; then echo bad ; fi
pax:/> if echo aBBd | grep '[A-Z][A-Z]' >/dev/null ; then echo bad ; fi
bad

Simplemente reemplace la cadena fija que se repite con su nombre de archivo real.



------------------------------------

Puedes utilizar el *[[:upper:]][[:upper:]]* glob:

$ cd "$(mktemp --directory)"
$ touch {a,A}{b,B}{c,C}.jpg
$ ls
abc.jpg  abC.jpg  aBc.jpg  aBC.jpg  Abc.jpg  AbC.jpg  ABc.jpg  ABC.jpg
$ ls *[[:upper:]][[:upper:]]*
aBC.jpg  ABc.jpg  ABC.jpg

Esto será mucho más rápido que recorrer la lista completa de archivos y verificar el patrón de ellos individualmente.



------------------------------------

Puedes combinar algunas de esas pruebas juntas:

for file in *.jpg; do
    if [[ $file =~ [[:space:]_]|[[:upper:]]{2} ]] || [[ $file != *-original.jpg ]]
        then
        echo "Filename issue: $file"
        i=$((i+1))
    fi
done

Primero use una expresión regular para buscar espacios, guiones bajos o dos letras mayúsculas consecutivas, y luego un patrón comodín para ver si el archivo no termina en -original.jpg. Si cualquiera de las pruebas tiene éxito, es un nombre de archivo no válido. Si ambos fallan, está bien.



------------------------------------

Para probar de manera simple y eficiente si (1) no hay espacios, (2) sin guiones bajos, (3) sin letras mayúsculas consecutivas, (4) y cada nombre de archivo debe terminar en "-original.jpg" usando cualquier awk POSIX en cualquier shell:

awk '
BEGIN {
    if ( ARGV[1] == "*.jpg" ) {
        exit
    }
    for (i=1; i<ARGC; i++) {
        fname = ARGV[i]
        if ( (fname ~ /[[:space:]_]|[[:upper:]]{2}/) || (fname !~ /-original\.jpg$/) ) {
            gotBad = 1
            print "Filename issue:", fname | "cat>&2"
        }
    }
}
END {
    if ( ! gotBad ) {
        print "No filename issues" | "cat>&2"
    }
    exit gotBad
}
' *.jpg

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare