如何将 raku -e 和 -n 与多个文件 glob 一起使用
How do I use raku -e and -n with multiple file glob
我想在 windows
的 raku 中进行以下操作
raku -n -e ".say if /mydatabegin/;" *.file
无法打开文件 C:\..\*.file: 参数无效
glob 未被解释为 glob。我认为那是因为 windows 要求您的程序自己进行通配?那么是否有预处理指令或函数,甚至是我可能错过或重定向的开关,或者允许在保持 -n(或 -p)和 -e 开关的简单性的同时扩展 glob 的东西?
显然,我可以通过删除 -n(或 -p)将其更改为完整程序,只需使用 -e 指定一个 main,然后在 glob 结果上循环。但是我真的很喜欢-n.
PS。我真的只是在学习 raku,并且很惊讶这不是开箱即用的。因此,具有简单语法的完整程序示例也可以工作。但是我真的很喜欢-n..
编辑:回复@chenyf
raku -e ".say for $*ARGFILES" *.file
同样的错误。相关:
raku -e ".say for $*ARGFILES.lines" *.file
同样的错误。
raku -e "use IO::Glob; .say for glob('*.file')"
按预期工作!展开:
raku -e "use IO::Glob; .say for glob('*.file').lines"
'lines' 类型 'IO::Glob'
的调用者没有这样的方法
越来越接近 - 或许对此进行扩展是一个足够好的解决方法。但回到一线荣耀尝试:
raku -e "use IO::Glob; .say for glob($*ARGFILES)" test.file
无法解析调用者 glob(IO::ArgFiles:D); none 个签名匹配。
好的 - 让我们回到字符串的安全:
raku -e "use IO::Glob; .say for glob($*ARGFILES.Str)" test.file
是的!所以..:[=24=]
raku -e "use IO::Glob; .say for glob($*ARGFILES.Str).lines" test.file
'lines' 类型 'IO::Glob'
的调用者没有这样的方法
我显然需要阅读更多手册。但是让我们稍微退后一步,看看我的用例是否有效:
raku -e "use IO::Glob; .say for glob($*ARGFILES.Str)" *.file
无法打开文件 C:\..\*.file: 参数无效
我一开始就犯了同样的错误。这可能只是 windows 错误的 raku 吗?
编辑:
raku -MIO::Glob -e "my @files = (map { glob($_).dir }, @*ARGS).flat; for @files -> $file { say $_ for $file.lines }" *file *file2 *5
我有三套档案。我几乎可以接受这个解决方案 - 除了某些原因,这些行被打印为 "s
关于缩短和删除引号的任何想法?
编辑 解决 $*ARGFILES 变量的自动通配:
raku -MIO::Glob -n -e "BEGIN { @*ARGS = (map { glob($_) }, @*ARGS).flat }; .say" *.file *.file2
这样做的好处是仍然看起来像原来的内衬;它使用-n!它只需要在创建 $*ARGFILES 时进行通配,这似乎是一个错误。
raku -MIO::Glob -e "BEGIN { @*ARGS = (map { glob($_) }, @*ARGS).flat }; .say for $*ARGFILES.lines" *.file *.file2
上面转换为 $*ARGFILES.lines 表明 $*ARGFILES 从 @*ARGS 动态获取它的值。
编辑
最后,事实证明 glob 函数不适用于目录,至少在 windows 上是这样(documentation 有一个根本不起作用的示例)。
#Example from https://github.com/zostay/raku-IO-Glob
for glob("src/core/*.pm") -> $file { say ~$file }
#mine that doesn't work
raku -MIO::Glob -e "for glob('..\*.file') -> $file { say ~$file }"
#mine that does work.
raku -MIO::Glob -e "for glob('*.file').dir('..') -> $file { say ~$file }"
#And therefore the final modification of the script above:
raku -MIO::Glob -e "BEGIN { @*ARGS = (map { glob(.IO.basename).dir(.IO.dirname) }, @*ARGS).flat }; .say for $*ARGFILES.lines" ..\*.file
我对文件通配的基本理解是 shell 处理这个问题——而且由于您似乎在 Windows,所有的赌注都可能被取消。唯一的例外可能是如果您使用 WSL
Windows-Subsystem-for-Linux,这应该会给您更多 Unix/Linux-like 体验:
https://docs.microsoft.com/en-us/windows/wsl/about
根据下面的 Microsoft 文档,Windows 有两个内置的 shells,CMD.exe 和 Powershell(我相信 WSL shell以上是可选的):
"命令Shell概述"
"Windows有两个命令shell:The Commandshell和PowerShell。每个shell是一个软件在您与操作系统或应用程序之间提供直接通信的程序,提供自动化 IT 操作的环境。"
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands
以下是在相当老的 bash/MacOS
系统上运行的内容。
使用 -ne
(非自动打印)命令行标志:
raku -ne 'print $_ ~ "\n";'
raku -ne 'say $_ ;'
raku -ne '.say;'
使用-pe
(自动打印)命令行标志:
raku -pe 'print "";'
raku -pe ''
我实际上只是使用上面的命令打印了五 (5) 个 *.txt
文件的内容。 -e
标志始终结束您的命令行标志簇,但 可以 组合(请参阅下面的 -M
标志以了解例外情况)。
现在因为您在 Windows,您可能需要将 ""
双引号替换为 ''
单引号(反之亦然!)。但希望这能让你开始。 [任何其他问题,您可能必须指定 Rakudo 可执行文件的完整路径]。
如果您希望 Raku 为您处理目录修改,可以使用 Raku 的 dir()
命令,该命令可以与其 :test
副词(参数)结合使用。下面比较上述目录中有五 (5) 个 *.txt
个文本文件,(删除 .elems
打印实际文本的调用):
raku -e '.lines.elems.say for dir(test => / \.txt $ /);'
14
16
34
1
16
对比:
raku -e '.lines.elems.say for $*ARGFILES;' *.txt
81
https://docs.raku.org/routine/dir
附录:我对 Raku P5-to-P6 词汇表的检查表明,设计者故意将 Perl5 的 glob
功能排除在 Perl6/Raku 之外,而是选择更强大的内置 dir()
套路。链接如下:
https://docs.raku.org/language/5to6-perlfunc#index-entry-glob_-_perlfunc
https://docs.raku.org/routine/dir
Raku 模块 IO::Glob
是非核心的(而且..我从未尝试过)。但是如果你在命令行工作并想加载一个模块,你可以使用(例如)-MIO::Glob
后跟 -e
、-ne
或 -pe
等.(此外,无需在您的 Raku 单行中加入 use IO::Glob;
行,它已经通过 -M
加载)。
在下面的链接中查看带有 Txt::CSV
模块 and/or XML
模块的 Raku 单行示例:
https://unix.stackexchange.com/search?q=%5Bcsv%5D+Raku
https://unix.stackexchange.com/search?q=%5Bxml%5D+Raku
关注下面的额外WindowsCMD.exediscussion/resolution:
一般答案 - 这不是错误。 Windows 如果需要,程序必须处理它们自己的 globbing。让它在 raku 可执行文件中工作对我来说很有意义;它消除了平台特定的惊喜,并使单线更容易。
但其他人不这么看,有一个足够简单的解决方案 - 创建自己的模块,以便代码保持一致并相对简单地调用。
这是一个初学者模块。有空间可以添加
之类的东西
- 强制成功匹配的开关
- 指示失败的 glob 应保留在 @*ARGS 变量中的开关
- 在它之后切换到仅 glob。
- 应用通配而不是自动执行的例程。这将允许您删除非文件开关
- 将每个 glob 收集到自己的列表中(可能需要一个开关)。
模块:
unit module CLGlob:ver<1.0>:auth<pureabsolute>;
use IO::Glob;
@*ARGS = map { .Str }, (map { glob(.IO.basename).dir(.IO.dirname) }, @*ARGS ).flat;
注意:当 glob 函数适用于 windows 目录时,可以简化第二个映射中的表达式。
注意:我将每个元素都转换为 .Str 以使 @*ARGS 保持一致。 $*ARGFILES 无需执行此操作即可工作,因此如果您再也不会查看 @*ARGS,则可以节省一些处理。
最后,最终结果:
raku -MCLGlob -ne ".say" ..\*.file ..\*.file2
赞。
我想在 windows
的 raku 中进行以下操作raku -n -e ".say if /mydatabegin/;" *.file
无法打开文件 C:\..\*.file: 参数无效
glob 未被解释为 glob。我认为那是因为 windows 要求您的程序自己进行通配?那么是否有预处理指令或函数,甚至是我可能错过或重定向的开关,或者允许在保持 -n(或 -p)和 -e 开关的简单性的同时扩展 glob 的东西?
显然,我可以通过删除 -n(或 -p)将其更改为完整程序,只需使用 -e 指定一个 main,然后在 glob 结果上循环。但是我真的很喜欢-n.
PS。我真的只是在学习 raku,并且很惊讶这不是开箱即用的。因此,具有简单语法的完整程序示例也可以工作。但是我真的很喜欢-n..
编辑:回复@chenyf
raku -e ".say for $*ARGFILES" *.file
同样的错误。相关:
raku -e ".say for $*ARGFILES.lines" *.file
同样的错误。
raku -e "use IO::Glob; .say for glob('*.file')"
按预期工作!展开:
raku -e "use IO::Glob; .say for glob('*.file').lines"
'lines' 类型 'IO::Glob'
的调用者没有这样的方法越来越接近 - 或许对此进行扩展是一个足够好的解决方法。但回到一线荣耀尝试:
raku -e "use IO::Glob; .say for glob($*ARGFILES)" test.file
无法解析调用者 glob(IO::ArgFiles:D); none 个签名匹配。
好的 - 让我们回到字符串的安全:
raku -e "use IO::Glob; .say for glob($*ARGFILES.Str)" test.file
是的!所以..:[=24=]
raku -e "use IO::Glob; .say for glob($*ARGFILES.Str).lines" test.file
'lines' 类型 'IO::Glob'
的调用者没有这样的方法我显然需要阅读更多手册。但是让我们稍微退后一步,看看我的用例是否有效:
raku -e "use IO::Glob; .say for glob($*ARGFILES.Str)" *.file
无法打开文件 C:\..\*.file: 参数无效
我一开始就犯了同样的错误。这可能只是 windows 错误的 raku 吗?
编辑:
raku -MIO::Glob -e "my @files = (map { glob($_).dir }, @*ARGS).flat; for @files -> $file { say $_ for $file.lines }" *file *file2 *5
我有三套档案。我几乎可以接受这个解决方案 - 除了某些原因,这些行被打印为 "s
关于缩短和删除引号的任何想法?
编辑 解决 $*ARGFILES 变量的自动通配:
raku -MIO::Glob -n -e "BEGIN { @*ARGS = (map { glob($_) }, @*ARGS).flat }; .say" *.file *.file2
这样做的好处是仍然看起来像原来的内衬;它使用-n!它只需要在创建 $*ARGFILES 时进行通配,这似乎是一个错误。
raku -MIO::Glob -e "BEGIN { @*ARGS = (map { glob($_) }, @*ARGS).flat }; .say for $*ARGFILES.lines" *.file *.file2
上面转换为 $*ARGFILES.lines 表明 $*ARGFILES 从 @*ARGS 动态获取它的值。
编辑
最后,事实证明 glob 函数不适用于目录,至少在 windows 上是这样(documentation 有一个根本不起作用的示例)。
#Example from https://github.com/zostay/raku-IO-Glob
for glob("src/core/*.pm") -> $file { say ~$file }
#mine that doesn't work
raku -MIO::Glob -e "for glob('..\*.file') -> $file { say ~$file }"
#mine that does work.
raku -MIO::Glob -e "for glob('*.file').dir('..') -> $file { say ~$file }"
#And therefore the final modification of the script above:
raku -MIO::Glob -e "BEGIN { @*ARGS = (map { glob(.IO.basename).dir(.IO.dirname) }, @*ARGS).flat }; .say for $*ARGFILES.lines" ..\*.file
我对文件通配的基本理解是 shell 处理这个问题——而且由于您似乎在 Windows,所有的赌注都可能被取消。唯一的例外可能是如果您使用 WSL
Windows-Subsystem-for-Linux,这应该会给您更多 Unix/Linux-like 体验:
https://docs.microsoft.com/en-us/windows/wsl/about
根据下面的 Microsoft 文档,Windows 有两个内置的 shells,CMD.exe 和 Powershell(我相信 WSL shell以上是可选的):
"命令Shell概述"
"Windows有两个命令shell:The Commandshell和PowerShell。每个shell是一个软件在您与操作系统或应用程序之间提供直接通信的程序,提供自动化 IT 操作的环境。"
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands
以下是在相当老的 bash/MacOS
系统上运行的内容。
使用 -ne
(非自动打印)命令行标志:
raku -ne 'print $_ ~ "\n";'
raku -ne 'say $_ ;'
raku -ne '.say;'
使用-pe
(自动打印)命令行标志:
raku -pe 'print "";'
raku -pe ''
我实际上只是使用上面的命令打印了五 (5) 个 *.txt
文件的内容。 -e
标志始终结束您的命令行标志簇,但 可以 组合(请参阅下面的 -M
标志以了解例外情况)。
现在因为您在 Windows,您可能需要将 ""
双引号替换为 ''
单引号(反之亦然!)。但希望这能让你开始。 [任何其他问题,您可能必须指定 Rakudo 可执行文件的完整路径]。
如果您希望 Raku 为您处理目录修改,可以使用 Raku 的 dir()
命令,该命令可以与其 :test
副词(参数)结合使用。下面比较上述目录中有五 (5) 个 *.txt
个文本文件,(删除 .elems
打印实际文本的调用):
raku -e '.lines.elems.say for dir(test => / \.txt $ /);'
14
16
34
1
16
对比:
raku -e '.lines.elems.say for $*ARGFILES;' *.txt
81
https://docs.raku.org/routine/dir
附录:我对 Raku P5-to-P6 词汇表的检查表明,设计者故意将 Perl5 的 glob
功能排除在 Perl6/Raku 之外,而是选择更强大的内置 dir()
套路。链接如下:
https://docs.raku.org/language/5to6-perlfunc#index-entry-glob_-_perlfunc https://docs.raku.org/routine/dir
Raku 模块 IO::Glob
是非核心的(而且..我从未尝试过)。但是如果你在命令行工作并想加载一个模块,你可以使用(例如)-MIO::Glob
后跟 -e
、-ne
或 -pe
等.(此外,无需在您的 Raku 单行中加入 use IO::Glob;
行,它已经通过 -M
加载)。
在下面的链接中查看带有 Txt::CSV
模块 and/or XML
模块的 Raku 单行示例:
https://unix.stackexchange.com/search?q=%5Bcsv%5D+Raku
https://unix.stackexchange.com/search?q=%5Bxml%5D+Raku
关注下面的额外WindowsCMD.exediscussion/resolution:
一般答案 - 这不是错误。 Windows 如果需要,程序必须处理它们自己的 globbing。让它在 raku 可执行文件中工作对我来说很有意义;它消除了平台特定的惊喜,并使单线更容易。
但其他人不这么看,有一个足够简单的解决方案 - 创建自己的模块,以便代码保持一致并相对简单地调用。
这是一个初学者模块。有空间可以添加
之类的东西- 强制成功匹配的开关
- 指示失败的 glob 应保留在 @*ARGS 变量中的开关
- 在它之后切换到仅 glob。
- 应用通配而不是自动执行的例程。这将允许您删除非文件开关
- 将每个 glob 收集到自己的列表中(可能需要一个开关)。
模块:
unit module CLGlob:ver<1.0>:auth<pureabsolute>;
use IO::Glob;
@*ARGS = map { .Str }, (map { glob(.IO.basename).dir(.IO.dirname) }, @*ARGS ).flat;
注意:当 glob 函数适用于 windows 目录时,可以简化第二个映射中的表达式。
注意:我将每个元素都转换为 .Str 以使 @*ARGS 保持一致。 $*ARGFILES 无需执行此操作即可工作,因此如果您再也不会查看 @*ARGS,则可以节省一些处理。
最后,最终结果:
raku -MCLGlob -ne ".say" ..\*.file ..\*.file2
赞。