为什么我的 Perl one-liner 在 Windows 上不起作用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/660624/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 12:10:16  来源:igfitidea点击:

Why doesn't my Perl one-liner work on Windows?

windowsperl

提问by gatorfax

From the Windows command prompt I generate a text file of all the files in a directory:

在 Windows 命令提示符下,我生成一个包含目录中所有文件的文本文件:

dir c:\logfiles /B > config.txt

Output:

输出:

0001_832ec657.log
0002_a7c8eafc.log

I need to feed the "config.txt" file to another executable, but before I do so, I need to modify the file to add some additional information that the executable needs. So I use the following command:

我需要将“config.txt”文件提供给另一个可执行文件,但在此之前,我需要修改该文件以添加一些可执行文件所需的附加信息。所以我使用以下命令:

perl -p -i.bak -e 's/log/log,XYZ/g' config.txt

I'm expecting the result to be:

我期待的结果是:

0001_832ec657.log,XYZ
0002_a7c8eafc.log,XYZ

However, the "config.txt" file is not modified. Using the "-w" option, I get the warning message:

但是,“config.txt”文件没有被修改。使用“-w”选项,我收到警告消息:

Useless use of a constant in void context at -e line 1.

在 -e 第 1 行的 void 上下文中无用地使用常量。

What am I doing wrong?

我究竟做错了什么?

回答by ephemient

Windows cmd.exedoes not use 'as string delimiters, only ". What you're doing is equivalent to:

Windowscmd.exe不用'作字符串分隔符,仅用作". 你在做什么相当于:

perl -p -i.bak -e "'s/log/log,XYZ/g'" config.txt

so -wis complaining "you gave me a string but it does nothing".

所以-w抱怨“你给了我一个字符串,但它什么也没做”。

The solution is to use double quotes instead:

解决方案是改用双引号:

perl -p -i.bak -e "s/log/log,XYZ/g" config.txt

or to simply leave them off, since there's no metacharacters in this command that would be interpreted by cmd.exe.

或者干脆不理会它们,因为在这个命令中没有元字符会被cmd.exe.

Addendum

附录

cmd.exeis just a really troublesome beast, for anybody accustomed to sh-like shells. Here's a few other common failures and workarounds regarding perlinvocation.

cmd.exe对于习惯了sh贝壳的人来说,简直就是个麻烦的野兽。以下是有关perl调用的其他一些常见故障和解决方法。

@REM doesn't work:
perl -e"print"
@REM works:
perl -e "print"
@REM doesn't work:
perl -e "print \"Hello, world!\n\""
@REM works:
perl -e "print qq(Hello, world!\n)"

回答by Chas. Owens

ephemient's answer summarizes the problem well, but you do have another option: change your shell from cmd.exeto a better shell. If you are a Unix type person then I would suggest looking into Cygwinwhich provides the sort of environment you are used to (for example, Bashand GNU utilities).

ephemient的回答很好地总结了这个问题,但您确实有另一种选择:将您的 shell 从cmd.exe更改为更好的 shell。如果您是 Unix 类型的人,那么我建议您查看Cygwin,它提供了您习惯的那种环境(例如,Bash和 GNU 实用程序)。

If you are a Windows-type person I would suggest looking at PowerShell(née MSH née Monad). In fact, I would suggest looking into PowerShell even if you are Unix type person. It integrates with .NETand has many neat features (like objects being passed through pipes rather than simple lines of text). If I were stuck on a Microsoft OS, it is the shell I would be using.

如果您是 Windows 类型的人,我建议您查看PowerShell(née MSH née Monad)。事实上,即使您是 Unix 类型的人,我也建议您查看 PowerShell。它与.NET集成并具有许多简洁的功能(例如通过管道传递的对象而不是简单的文本行)。如果我被困在 Microsoft 操作系统上,它就是我将使用的外壳。

Other shells for Windows that people seem to like:

人们似乎喜欢的其他 Windows 外壳: