首页 > 解决方案 > Perl 单线 Windows 10 / Power Shell:替换以 *.sql 结尾的多个文件中的字符串将不起作用(* globing 无法识别)

问题描述

以下单行 Perl 语句在使用“*”通配符时不起作用:

>>> perl -i'.bak' -pe 's#__SUB__CWD__#'$(pwd)'#g' *.sql
Can't open *.sql: Invalid argument. 

以下语句有效,但仅当您将单个文件作为参数提供时:

>>> perl -p -i'.bak' -e 's#__SUB__CWD__#'$(pwd)'#g' A_SINGLE_FILE.sql

知道什么可以使 perl 实现“*”必须以 REGEX 方式读取吗?

我正在尝试替换大量文件中所有出现的“ SUB__CWD ”。

参见https://github.com/oracle/db-sample-schemas/blob/master/README.md

标签: windowspowershellperlglob

解决方案


这不是 Perl 的错,而是 Windows 的错。Linux shell 会为您扩展通配符,而 cmd.exe 不会。我不了解 PowerShell,但似乎也不了解。

此外,您不想以正则表达式的方式解释星号,而是以 glob 模式的方式。在正则表达式中,*表示“前一件事应该重复零次或多次”。

您可以使用 Perl 的glob函数:

perl -p -i'.bak' -e 'BEGIN {@ARGV = glob shift} s#__SUB__CWD__#'$(pwd)'#g' *.sql

请注意,您需要在路径中添加反斜杠以防止 Perl 解释它们,即使用$($pwd -replace '\\', '\\')而不是仅使用$(pwd). 您还需要反斜杠#路径中的字符,否则它们会被理解为分隔符,因此请使用$($pwd -replace '[\\#]', '\$&').

因此,不使用会更干净$(pwd),但让 Perl 知道替换是什么:

perl -p -i'.bak' -e 'BEGIN{ ($pwd, @ARGV) = (shift, map glob, @ARGV) }
                   s/__SUB__CWD__/$pwd/g' -- $(pwd) *.sql

第一个参数$pwd通过shift分配,其余属性映射到 glob,这意味着您可以指定多个通配符模式。


推荐阅读