¿Cómo puedo hacer que un archivo por lotes actúe como un simple grep usando Perl?

votos
9

Ya sé la respuesta obvia a esta pregunta: simplemente descargue <inserte Windows grep o grep-like tool aquí>. Sin embargo, trabajo en un entorno con controles estrictos por parte del personal de TI local en cuanto a lo que se nos permite tener en nuestras computadoras. Baste decir: tengo acceso a Perl en Windows XP. Aquí hay un script rápido de Perl que se inventó que hace lo que yo quiero, pero no he descubierto cómo configurar un archivo por lotes de modo que pueda canalizar un resultado de comando en él o pasar un archivo (o una lista de archivos) ?) como argumento después de la expresión a grep:

perl -n -e print $ _ if (m! [expresión]!); [nombre del archivo]

¿Cómo escribo un script por lotes que puedo hacer algo como, por ejemplo:

dir | grep.bat mypattern
grep.bat mypattern myfile.txt

EDITAR : Aunque marqué otra respuesta, quería felicitar a Ray Hayes por su respuesta , ya que es realmente la Manera de Windows para hacerlo, incluso si otra respuesta está más cerca de lo que quería técnicamente.

Publicado el 19/09/2008 a las 23:10
fuente por usuario
En otros idiomas...                            


6 respuestas

votos
26

La mayor parte de la potencia de grep ya está disponible en su máquina en la aplicación de Windows FindStr.exe que es parte de todas las máquinas con Windows 2000, XP y Vista. Ofrece RegExpr, etc.

¡Mucho más fácil que un archivo por lotes que a su vez llama a Perl!

c:\>FindStr /?    
Searches for strings in files.

FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] [/F:file]
        [/C:string] [/G:file] [/D:dir list] [/A:color attributes] [/OFF[LINE]]
        strings [[drive:][path]filename[ ...]]

  /B         Matches pattern if at the beginning of a line.
  /E         Matches pattern if at the end of a line.
  /L         Uses search strings literally.
  /R         Uses search strings as regular expressions.
  /S         Searches for matching files in the current directory and all
             subdirectories.
  /I         Specifies that the search is not to be case-sensitive.
  /X         Prints lines that match exactly.
  /V         Prints only lines that do not contain a match.
  /N         Prints the line number before each line that matches.
  /M         Prints only the filename if a file contains a match.
  /O         Prints character offset before each matching line.
  /P         Skip files with non-printable characters.
  /OFF[LINE] Do not skip files with offline attribute set.
  /A:attr    Specifies color attribute with two hex digits. See "color /?"
  /F:file    Reads file list from the specified file(/ stands for console).
  /C:string  Uses specified string as a literal search string.
  /G:file    Gets search strings from the specified file(/ stands for console).
  /D:dir     Search a semicolon delimited list of directories
  strings    Text to be searched for.
  [drive:][path]filename
             Specifies a file or files to search.

Use spaces to separate multiple search strings unless the argument is prefixed
with /C.  For example, 'FINDSTR "hello there" x.y' searches for "hello" or
"there" in file x.y.  'FINDSTR /C:"hello there" x.y' searches for
"hello there" in file x.y.

Regular expression quick reference:
  .        Wildcard: any character
  *        Repeat: zero or more occurances of previous character or class
  ^        Line position: beginning of line
  $        Line position: end of line
  [class]  Character class: any one character in set
  [^class] Inverse class: any one character not in set
  [x-y]    Range: any characters within the specified range
  \x       Escape: literal use of metacharacter x
  \<xyz    Word position: beginning of word
  xyz\>    Word position: end of word
Respondida el 19/09/2008 a las 23:18
fuente por usuario

votos
11

Descargue e instale ack . Es un reemplazo superior para grep y, gracias al mágico modo de perl Magia de secuencia de comandos .BAT / Perl, funcionará en la línea de comandos para ti.

Respondida el 19/09/2008 a las 23:49
fuente por usuario

votos
5

Primero, conviértalo en una secuencia de comandos real en lugar de una sola línea:

use strict;
use warnings;

my $pattern = shift or die "Usage: $0 <pattern> [files|-]\n";
while (<>) { print if /$pattern/ }

Luego conviértalo en un archivo por lotes usando pl2bat:

pl2bat mygrep.pl

Esto creará "mygrep.bat".

Para un grep con todas las funciones (y muchas otras aplicaciones de Unix) escritas completamente en Perl, vea el proyecto Perl Power Tools .

Si bien Perl Power Tools es bueno si solo puedes ejecutar Perl, generalmente prefiero el conjunto de herramientas GnuWin32 . No requieren instalación. (No necesita privilegios administrativos, solo un directorio en el que puede escribir).

Respondida el 20/09/2008 a las 00:15
fuente por usuario

votos
5

Escribí esto hace un tiempo:

@rem = '--*-Perl-*--
@echo off
perl -x -S %0 %*
goto endofperl


@rem -- BEGIN PERL -- ';
#!d:/Perl/bin/perl.exe -w
#line 10
use strict; 
#use Test::Setup;
use Getopt::Long;

Getopt::Long::Configure ("bundling");

my $ignore_case    = 0;
my $number_line    = 0;
my $invert_results = 0;
my $verbose        = 0;

my $result = GetOptions( 
    'i|ignore_case' => \$ignore_case, 
    'n|number'      => \$number_line,
    'v|invert'      => \$invert_results,
    'verbose'       => \$verbose,
);
my $regex = shift;

if ( $ignore_case ) { 
    $regex = "(?i:$regex)";
}
$regex = qr/$regex/;
print "\$regex=$regex\n";
if ( $verbose ) { 
    print "Verbose: Ignoring case.\n"                      if $ignore_case;
    print "Verbose: Printing file name and line number.\n" if $number_line;
    print "Verbose: Inverting result set.\n"               if $invert_results;
    print "\n";
}

@ARGV = map { glob "$_" } @ARGV;

while ( <> ) { 
    my $matches = m/$regex/;
    next unless $matches ^ $invert_results;
    print "$ARGV\:$.:" if $number_line;
    print;
}

__END__
:endofperl
Respondida el 19/09/2008 a las 23:29
fuente por usuario

votos
1

Estoy de acuerdo con Axeman y el Sr. Hayes sobre el uso de una herramienta mejor para el trabajo. Dicho esto, podría intentar algo como esto en su archivo por lotes para ejecutar su script personalizado contra una expresión de comodín de archivo:

@echo off

for /f "usebackq delims==" %%f in (`dir /w /b %2`) do (
    perl -n -e "print $_ if (m!%1!);" "%%f"
    REM or something like:  myperlscript.pl %1 "%%f"
)

De esta forma, puedes hacer cosas como "grep mypattern myfile.txt", "grep mypattern.", "Grep mypattern * .doc", etc.

Respondida el 19/09/2008 a las 23:39
fuente por usuario

votos
1

Debes hacer algo como esto:

@echo off
perl -x -S script.pl %1

El "% 1" pasará el argumento al script de Perl. Guárdelo como un archivo .bat, y listo.

Respondida el 19/09/2008 a las 23:19
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more