Verificación de nombres de archivo dentro de un directorio con expresiones regulares

5

Tengo una lista de archivos dentro de un directorio y quiero hacer un script bash que use una expresión regular para verificar si cada nombre de archivo tiene esta sintaxis:

xxxx_xxxx_xx_xx

Donde x son números.

Editar: solo necesito con la expresión regular

Federico Ponzi
fuente

Respuestas:

8

Qué tal si

#/usr/bin/env bash
for f in *
do
  [[ $f =~ [0-9]{4}_[0-9]{4}_[0-9]{2}_[0-9]{2} ]] || 
    echo "File $f does not match"
done

La expresión regular verifica cualquier dígito ( [0-9]). Los números entre llaves son el número de repeticiones, por [0-9]{4}lo que coincidirán con 4 dígitos.

Recomendaría que no use bash para esto, sino que busque en su lugar. Probablemente será más rápido, y ciertamente es más portátil (no todos los shells pueden manejar expresiones regulares):

find -regextype posix-egrep -not -regex '\./[0-9]{4}_[0-9]{4}_[0-9]{2}_[0-9]{2}'
terdon
fuente
No puedo construir un escenario que haga que su findcomando se rompa, pero sigo creyendo (en principios generales) que la expresión regular probablemente debería citarse, por seguridad.
Scott
@Scott Tiendo a estar de acuerdo con esas citas de precaución, pero no conozco ningún caparazón que se ahogue con eso. Aún así, como dijiste, más vale prevenir que curar. Cotizaciones agregadas.
terdon
Bien, recibí mi n + 1ª inyección de cafeína y lo descubrí. No es un problema de asfixia de shell , per se . Si hay un archivo en el directorio actual con un nombre como 5{4}_3{4}_0{2}_9{2}(y no tiene desactivado el bloqueo de shell), entonces \./[0-9]{4}_[0-9]{4}_[0-9]{2}_[0-9]{2}(su expresión regular) se expandirá ./5{4}_3{4}_0{2}_9{2}y findsolo coincidirá ./5555_3333_00_99(si existe). ... ... (Por cierto, 5309 son los últimos cuatro dígitos del número de teléfono de Jenny.)
Scott
@ Scott ah, sí, ¡bien encontrado! Quien es Jenny? ¿O no debería preguntar?
terdon
¿Seriamente? Oh ya veo; no vives en un país principalmente de habla inglesa. Aqui tienes.
Scott
1

Es torpe, pero esto debería ser muy portátil:

#! / bin / sh
para x en *
hacer
    caso "$ x" en
        [0-9] [0-9] [0-9] [0-9] _ [0-9] [0-9] [0-9] [0-9] _ [0-9] [0- 9] _ [0-9] [0-9])
            echo "$ x coincide"
            ;;
        *)
            echo "$ x no coincide"
    esac
hecho
#                        Y, para ser molestamente completo,
para x pulg. *
hacer
    echo "$ x no coincide"
hecho
Scott
fuente
La misma expresión regular que usé, por cierto, creo que la solución provista por @terdon es más limpia. ¡Gracias de cualquier manera!
Federico Ponzi