Come posso fare in modo che un file batch si comporti come un semplice grep usando Perl?

StackOverflow https://stackoverflow.com/questions/106053

  •  01-07-2019
  •  | 
  •  

Domanda

Conosco già la risposta ovvia a questa domanda: " basta scaricare < inserire qui lo strumento windows grep o grep preferito > " ;. Tuttavia, lavoro in un ambiente con severi controlli da parte del personale IT locale su ciò che ci è permesso avere sui nostri computer. Basti dire: ho accesso a Perl su Windows XP. Ecco un veloce script Perl che ho ideato che fa quello che voglio, ma non ho capito come impostare un file batch in modo da poter reindirizzare un comando in uscita o passare un file (o un elenco di file ?) come argomento dopo l'espressione " in grep " ;:

perl -n -e "print $_ if (m![expression]!);" [filename]

Come posso scrivere uno script batch che posso fare qualcosa del genere, ad esempio:

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

EDIT : anche se ho segnato un altro " answer " ;, volevo dare i miei complimenti a Ray Hayes risponde , dato che è davvero il & Quot ; Windows Way & Quot; per farlo, anche se un'altra risposta è tecnicamente più vicina a ciò che volevo.

È stato utile?

Soluzione

L'ho scritto qualche tempo fa:

@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

Altri suggerimenti

La maggior parte della potenza di grep è già disponibile sul tuo computer nell'applicazione FindStr.exe di Windows che fa parte di tutti i computer Windows 2000, XP e Vista! Offre RegExpr ecc.

Molto più semplice di un file batch che a sua volta chiama 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

Scarica e installa ack . È un sostituto superiore di grep e - grazie alla doppia modalità magica di Perl .BAT / script di magia magica - funzionerà sulla riga di comando per te.

Innanzitutto, trasformalo in un vero script anziché in una riga:

use strict;
use warnings;

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

Quindi trasformalo in un file batch usando pl2bat:

pl2bat mygrep.pl

Questo creerà " mygrep.bat " ;.

Per un grep completo (e molte altre applicazioni Unix) scritto completamente in Perl, vedi Progetto Perl Power Tools .

Mentre gli utensili elettrici Perl sono buoni se si può eseguire solo Perl, in genere preferisco l'insieme di GnuWin32 strumenti. Non richiedono installazione. (Non hai bisogno di privilegi di amministratore, solo una directory in cui puoi scrivere.)

Sono d'accordo con Axeman e Mr. Hayes sull'utilizzo di uno strumento migliore per il lavoro. Detto questo, potresti provare qualcosa del genere nel tuo file batch per eseguire lo script personalizzato su un'espressione jolly di file:

@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"
)

In questo modo, puoi fare cose come " grep mypattern myfile.txt " ;, " grep mypattern. " ;, " grep mypattern * .doc " ;, ecc.

Devi fare qualcosa del genere:

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

Il "% 1 " passerà l'argomento allo script Perl. Salvalo come file .bat e sei a posto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top