Windows 如何使用Perl使批处理文件像简单的grep一样工作?

Windows 如何使用Perl使批处理文件像简单的grep一样工作?,windows,perl,batch-file,Windows,Perl,Batch File,我已经知道了这个问题的明显答案:“只需下载”。然而,我在一个由当地IT人员严格控制的环境中工作,他们允许我们在计算机上使用什么。我只想说:我可以在WindowsXP上访问Perl。下面是我想到的一个快速Perl脚本,它满足了我的需要,但我还没有想出如何设置批处理文件,以便我可以将命令输出导入其中,或者将文件(或文件列表?)作为参数传递到“expression to grep”之后: perl-n-e“print$\uif(m![expression]!);”[filename] 如何编写可以执行

我已经知道了这个问题的明显答案:“只需下载”。然而,我在一个由当地IT人员严格控制的环境中工作,他们允许我们在计算机上使用什么。我只想说:我可以在WindowsXP上访问Perl。下面是我想到的一个快速Perl脚本,它满足了我的需要,但我还没有想出如何设置批处理文件,以便我可以将命令输出导入其中,或者将文件(或文件列表?)作为参数传递到“expression to grep”之后:

perl-n-e“print$\uif(m![expression]!);”[filename] 如何编写可以执行以下操作的批处理脚本,例如:

dir | grep.bat mypattern grep.bat mypattern myfile.txt dir | grep.bat mypattern grep.bat mypattern myfile.txt
编辑:尽管我标记了另一个“答案”,但我还是想为之致敬,因为这确实是一种“Windows方式”,即使另一个答案在技术上更接近我想要的答案。

grep的大部分功能已经在您的计算机上的Windows应用程序FindStr.exe中可用,FindStr.exe是所有Windows 2000的一部分,XP和Vista机器!它提供RegExpr等

比调用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
c:\>FindStr/?
在文件中搜索字符串。
查找文件
[/C:string][/G:file][/D:dir list][/A:color attributes][/OFF[LINE]]
字符串[[drive:][path]文件名[…]]
/如果在一行的开头,B与模式匹配。
/如果在一行的末尾,E与模式匹配。
/L按字面意思使用搜索字符串。
/R使用搜索字符串作为正则表达式。
/S在当前目录和所有目录中搜索匹配的文件
子目录。
/I指定搜索不区分大小写。
/X打印完全匹配的线条。
/V仅打印不包含匹配项的行。
/N在匹配的每行之前打印行号。
/如果文件包含匹配项,则M仅打印文件名。
/O打印每个匹配行之前的字符偏移量。
/P跳过包含不可打印字符的文件。
/OFF[LINE]不跳过设置了offline属性的文件。
/答:attr使用两个十六进制数字指定颜色属性。请参阅“颜色/?”
/F:file从指定文件读取文件列表(/代表控制台)。
/C:string使用指定的字符串作为文本搜索字符串。
/G:file从指定的文件(/代表控制台)获取搜索字符串。
/D:dir搜索以分号分隔的目录列表
要搜索的字符串文本。
[drive:][path]文件名
指定要搜索的一个或多个文件。
除非参数带有前缀,否则使用空格分隔多个搜索字符串
使用/C。例如,“FINDSTR”hello there“x.y”搜索“hello”或
文件x.y.中的“there.”FINDSTR/C:“hello there”x.y'搜索
x.y文件中的“你好”。
正则表达式快速引用:
.        通配符:任何字符
*重复:前一个字符或类的零次或多次出现
^行位置:行的开头
$Line位置:行尾
[class]字符类:集合中的任意一个字符
[^class]反向类:集合中未包含的任何一个字符
[x-y]范围:指定范围内的任何字符
\x转义:元字符x的字面用法
\单词位置:单词末尾

您需要执行以下操作:

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

“%1”将把参数传递给Perl脚本。将它另存为.bat文件,就可以开始了。

我不久前写了这个:

@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
@rem='-*-Perl-*--
@回音
perl-x-S%0%*
转到endofperl
@rem——开始PERL——';
#!d:/Perl/bin/Perl.exe-w
#第10行
严格使用;
#使用Test::Setup;
使用Getopt::Long;
Getopt::Long::Configure(“绑定”);
我的$ignore_案例=0;
我的$number\u行=0;
我的$invert_结果=0;
我的$verbose=0;
my$result=GetOptions(
“i | ignore_case”=>\$ignore_case,
“n | number”=>\$number\u行,
“v | invert”=>\$invert\u结果,
'verbose'=>\$verbose,
);
我的$regex=班次;
如果($ignore_case){
$regex=“(?i:$regex)”;
}
$regex=qr/$regex/;
打印“\$regex=$regex\n”;
如果($verbose){
如果$ignore\u case,则打印“Verbose:忽略大小写。\n”;
打印“详细:打印文件名和行号。\n”如果$number\u行;
如果$invert\u results,则打印“Verbose:inversing result set.\n”;
打印“\n”;
}
@ARGV=map{glob“$\}@ARGV;
而{
my$matches=m/$regex/;
下一步除非$matches^$invert_结果;
如果$number\u行,则打印“$ARGV\:$。:”;
印刷品;
}
__结束__
:endofperl

我同意阿克塞曼和海斯先生关于使用更好的工具来完成这项工作的看法。也就是说,您可以在批处理文件中尝试以下操作,以针对文件通配符表达式运行自定义脚本:

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

通过这种方式,您可以执行诸如“grep mypattern myfile.txt”、“grep mypattern.”、“grep mypattern*.doc”等操作。

下载并安装。它是grep的高级替代品,而且由于Perl的magic dual mode.BAT/Perl script magic,它可以在命令行上为您工作。

首先,将它转换为真正的脚本,而不是一行:

use strict;
use warnings;

my $pattern = shift or die "Usage: $0 <pattern> [files|-]\n";
while (<>) { print if /$pattern/ }
这将创建“mygrep.bat”

有关完全用Perl编写的功能齐全的grep(以及许多其他Unix应用程序),请参阅该项目


虽然如果您只能运行Perl,Perl Power工具是不错的,但我通常更喜欢这套工具。它们不需要安装。(您不需要管理权限,只需要一个可以写入的目录。)

您想要grep-re语法还是更强大的perl语法?这太棒了!对于试图在Windows平台上“成功”的unix极客来说,这是一个很好的建议。即使它没有直接回答我的问题:-)好吧,我确实明确指出,我的PC上有一个严格的环境,允许我安装什么。
use strict;
use warnings;

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