nushell:将过滤文件列表传递给外部程序

nushell:将过滤文件列表传递给外部程序

我想为我找到一些文件,过滤它们并将它们传递给外部程序。例如:“使用 Git 还原名称包含‘GENERATED’的所有文件。”我尝试了几种变体,但都不起作用:

# Doesn't pass the files:
ls --all --full-paths **/* | find GENERATED | git checkout --

# Returns an error: "Cannot convert record<name: string, type: string, size: filesize, modified: date> to a string"
ls --all --full-paths **/* | find GENERATED | each { |it| git checkout -- $it }

# Returns an error for every file: "error: Path specification »?[37m/home/xxx/com.?[0m?[41;37mgwt?[0m?[37mplugins.?[0m?[41;37mgwt?[0m?[37m.eclipse.core.prefs?[0m« does not match any file known to git" [Manually translated into English]
ls --all --full-paths **/* | find GENERATED | each { |it| git checkout -- $it.name }

在 Nu 中正确的做法是什么?

我知道如何用 Bash 做到这一点。这个问题只是关于 Nu。:-)

答案1

最简洁、最精确的方法是这样的:

ls -af **/* | where name =~ 'GENERATED' | each { ^git checkout -- $in.name }

这使用where命令根据正则表达式过滤name列(在本例中,由于标志,包含完整路径和文件名)-在您的情况下。-af'GENERATED'

命令前面的插入符号git是为了确保你调用外部 git 命令。如果你确实想调用外部命令,那么这样做是个好习惯。如果你省略它,它可能会调用命令的内部版本。例如,ls调用 Nushell 的内部 ls 命令,而^ls将调用外部 ls 命令。文档:https://www.nushell.sh/book/escaping.html

它还使用$in包含管道结果的值。您无需将其each作为参数传递到闭包中 - 它会自动可用。文档:https://www.nushell.sh/book/pipelines.html

您可以使用find相反,它不太精确,因为它搜索结果表的所有列,而不是针对特定列。您还需要小心去除 ansi 代码,因此最好坚持使用where

ls -af **/* | find 'GENERATED' | get name | ansi strip | each { ^git checkout -- $in }

或者

ls -af **/* | find 'GENERATED' | update name { $in | ansi strip } | each { ^git checkout -- $in.name }

注意,我还没有用 git checkout 测试过,但是我确实尝试了一些其他 git 命令,并且以上所有命令都有效。

相关内容