2008-09-19 2 views
9

Ich kenne bereits die offensichtliche Antwort auf diese Frage: "einfach herunterladen < einfügen Lieblings-Windows-Grep oder grep-like Werkzeug hier >". Ich arbeite jedoch in einer Umgebung mit strengen Kontrollen durch die lokalen IT-Mitarbeiter, was wir auf unseren Computern haben dürfen. Es genügt zu sagen: Ich habe Zugriff auf Perl unter Windows XP. Hier ist ein kurzes Perl-Skript, das ich gemacht habe, das tut, was ich will, aber ich habe nicht herausgefunden, wie man eine Batch-Datei so einrichtet, dass ich entweder eine Befehlsausgabe dorthin leiten oder eine Datei (oder eine Liste von Dateien) übergeben kann obwohl:?) als Argument nach dem "Ausdruck grep":Wie kann ich eine Batch-Datei erstellen, die mit Perl wie ein einfacher Grep funktioniert?

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

wie kann ich eine Batch-Skript schreiben, das ich so etwas wie, zum Beispiel tun können:

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

EDIT Ich habe eine andere "Antwort" markiert, ich wollte Ray Hayes answer anerkennen, da es wirklich der "Windows Way" ist, um es zu tun, auch wenn eine andere Antwort technisch ist näher zu dem, was ich wollte.

+0

Möchten Sie die grep re-Syntax oder die leistungsfähigere Perl-Syntax? – Axeman

Antwort

5

Ich schrieb dieses eine Weile zurück:

@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 
+0

Dies war die erste Antwort "exakte Antwort", und es sieht genau so aus, wie ich gefragt habe. Aber wie bereits erwähnt, verwendet der "Windows Way" FINDSTR. Ich werde dieses kleine Skript jedoch definitiv in meinem Windows Perl-Repertoire behalten, und ich bin mir sicher, dass dies oder eine Variation davon manchmal nützlich sein wird! –

+0

Eigentlich hatte ich ein Grep-Tool auf meinem PC, aber ich wollte die Macht der Perl-Ausdrücke für die Suche. FindStr ist wahrscheinlich so gut wie grep, aber auch hier wird nicht nach Dateien gesucht. Ack, wie Dave Webb erwähnte, macht beides. – Axeman

25

Die meiste Leistung von grep ist bereits auf Ihrem Computer in der Windows-Anwendung FindStr.exe verfügbar, die Teil aller Windows 2000, XP und Vista-Maschinen ist! Es bietet RegExpr etc.

Viel einfacher als eine Batch-Datei, die wiederum 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 
+0

Das ist großartig! Und ein guter Ratschlag für einen Unix-Geek, der versucht, es auf der Windows-Plattform "zu schaffen". Auch wenn es meine Frage nicht direkt beantwortet :-) –

1

Sie brauchen so etwas wie dies zu tun:

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

Die "% 1" wird das Argument für die Perl-Skript übergeben. Speichern Sie es als BAT-Datei, und Sie können loslegen.

+0

Würde das mit einer Pipe funktionieren? Ich meine, wenn ich dich bat Datei wie diese 'gcc -MM-Dateien | Ihr Baby regexp'. Ich habe das mit 'ack' versucht und unerwartetes Verhalten bekommen. – Gauthier

1

ich mit Axeman und Mr. Hayes über die Verwendung von ein besseres Werkzeug für den Job zustimmen. Das heißt, Sie so etwas wie dies in Batch-Datei könnte versuchen, Ihre benutzerdefinierten Skript für eine Datei Wildcard Ausdruck auszuführen:

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

Auf diese Weise Sie Dinge wie „grep myPattern myfile.txt“ tun können „grep mypattern. "," grep mypattern * .doc "usw.

+0

Dies ist ein nützlicher Leckerbissen. Durch eine kleine Menge an Suchen habe ich im Internet sehr wenig über die Verwendung von Argumenten, Piping usw. in Batch-Dateien gefunden. Das schaltet definitiv eine Glühbirne des Verständnisses für mich ein, danke! –

11

Herunterladen und Installieren ack. Es ist ein überlegener Ersatz für Grep und - dank Perls magischem Dual-Modus .BAT/Perl Script Magic - wird es auf der Kommandozeile für Sie funktionieren.

+0

Nun, ich habe speziell angegeben, dass ich eine strenge Umgebung auf meinem PC habe, was ich installieren darf. Dies könnte jedoch eine gute Option sein, da es sich um einen reinen Quelldownload handelt und meine IT-Abteilung es wahrscheinlich rutschen lassen würde. Guter Vorschlag. –

+0

Ja, ich würde auch einen Vorschlag machen, aber dann weiß ich, dass manche IT-Abteilungen sogar unautorisierte Firefox-Plugins und Perl-Module strikt einhalten. Wenn Sie also Ihre eigenen Batch-Dateien schreiben können, können Sie dies tun. aber es sieht so aus, als wäre FindStr ein Sprung über DOS find. – Axeman

5

Zuerst machen es zu einem echten Skript anstelle eines Einzeiler:

use strict; 
use warnings; 

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

Dann schalten Sie ihn in eine Batch-Datei pl2bat mit:

pl2bat mygrep.pl 

Das erzeugt „mygrep.bat ".

Für ein vollständiges Grep (und viele andere Unix-Anwendungen), die vollständig in Perl geschrieben sind, siehe das Projekt Perl Power Tools.

Während die Perl-Power-Tools gut sind, wenn Sie nur Perl ausführen können, bevorzuge ich im Allgemeinen den Satz von Tools.Sie benötigen keine Installation. (Sie benötigen keine Administratorrechte, nur ein Verzeichnis, in das Sie schreiben können.)

Verwandte Themen