es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo hacer que las expresiones regulares funcionen en un script de Perl?

Estoy trabajando en un entorno basado en Linux Debian (específicamente un servidor Proxmox) y estoy escribiendo un script en Perl.

Mi problema es el siguiente: Tengo una carpeta con algunos archivos, cada archivo en esta carpeta tiene un número como nombre (por ejemplo: 100, 501, 102…). El número más bajo posible es 100 y no hay límite para el más grande.

Quiero que mi script solo devuelva los archivos cuyo nombre esté entre 100 y 500.
Entonces, escribo esto:

system(ls /la/ruta/hasta/mis/archivos | grep -E "^[1-4][0-9]{2}|5[0]{2}");

Creo que mi expresión regular y el comando son buenos porque cuando escribo esto en una terminal, funciona.
Pero en cuanto ejecuto mi script, obtengo estos mensajes de error:

Se encontró una cadena donde se esperaba un operador en la línea 3 de backupsrvproxmox.pl, cerca de "E "^[1-4][0-9]{2}|5[0]{2}""
(¿Necesitas predeclarar E?)
Modificador de expresión regular desconocido "/b" en la línea 3 de backupsrvproxmox.pl, al final de la línea
Error de sintaxis en la línea 3 de backupsrvproxmox.pl, cerca de "E "^[1-4][0-9]{2}|5[0]{2}""
La ejecución de backupsrvproxmox.pl se abortó debido a errores de compilación.

También intenté con egrep pero aún no funciona.

No entiendo por qué el mensaje de error menciona el modificador /b ya que solo uso enteros y no cadenas.

Entonces, ¡cualquier ayuda sería buena!

Tags:  ,

Answer

  1. Avatar for davy.ai

    Solución

    El problema con la expresión regular actual es que le falta un conjunto de paréntesis alrededor de la condición OR, lo que provoca que el carácter ‘|’ se interprete como un OR a nivel de bits en lugar de un OR de expresiones regulares. Además, el modificador ‘\b’ (límite de palabra) no es necesario para esta tarea.

    Aquí tienes una versión actualizada del comando con la expresión regular corregida:

    system("ls /la/ruta/hacia/mis/archivos | grep -E '^(1[0-9]{2}|2[0-9]{2}|3[0-9]{2}|4[0-9]{2}|500)$'");
    

    Esta expresión regular coincide con los números entre 100 y 500 inclusive. El carácter ‘|’ ahora está encerrado entre paréntesis para asegurarse de que se interpreta como un OR de expresiones regulares, y se ha eliminado el modificador ‘\b’.

    Ten en cuenta que generalmente no se recomienda analizar la salida del comando ls, en su lugar utiliza el módulo Perl File::Find para recorrer de forma recursiva el directorio y encontrar archivos.

    Aquí tienes un ejemplo de script que utiliza File::Find:

    use strict;
    use warnings;
    use File::Find;
    
    my $dir = '/la/ruta/hacia/mis/archivos';
    my $regex = qr/^(1[0-9]{2}|2[0-9]{2}|3[0-9]{2}|4[0-9]{2}|500)$/;
    
    # función anónima para procesar cada archivo encontrado
    my $process_file = sub {
        # comprueba si el nombre del archivo coincide con la expresión regular
        return unless $_ =~ $regex;
        # haz algo con el archivo
        print "$File::Find::name/$_\n";
    };
    
    # recorre el directorio y procesa cada archivo
    find($process_file, $dir);
    

Comments are closed.