无法将某些函数从bash重写为nushell

bq8i3lrv  于 2022-11-30  发布在  Shell
关注(0)|答案(1)|浏览(147)

我正在从bash转移到nushell。我的一个步骤就是转移这个函数:

ex ()
{
  if [ -f $1 ] ; then
    case $1 in
      *.tar.bz2)   tar xjf $1   ;;
      *.tar.gz)    tar xzf $1   ;;
      *.bz2)       bunzip2 $1   ;;
      *.rar)       unrar x $1     ;;
      *.gz)        gunzip $1    ;;
      *.tar)       tar xf $1    ;;
      *.tbz2)      tar xjf $1   ;;
      *.tgz)       tar xzf $1   ;;
      *.zip)       unzip $1     ;;
      *.Z)         uncompress $1;;
      *.7z)        7z x $1      ;;
      *)           echo "'$1' cannot be extracted via ex()" ;;
    esac
  else
    echo "'$1' is not a valid file"
  fi
}

我在纽谢尔写道:

def ex [$file?: string] {
        if $file == null {"No file defined"} else {
                if $file == *.tar.bz2 {
                        tar xjf $file;
                }
                else if $file == *.tar.gz {
                        tar xzf $file;
                }
                else if $file == *.bz2 {
                        bunzip2 $file;
                }
                else if $file == *.rar {
                        unzip $file;
                }
                else if $file == *.gz {
                        gunzip $file;
                }
                else if $file == *.tar {
                        tar xf $file;
                }
                else if $file == *.tbz2 {
                        tar xjf $file;
                }
                else if $file == *.tgz {
                        tar xzf $file;
                }
                else if $file == *.zip {
                        unzip $file;
                }
                else if $file == *.Z {
                        uncompress $file;
                }
                else if $file == *.7z {
                        7z x $file;
                }
        }
}

但是当我用这个命令测试它的时候(我在执行命令的目录下有一个openssl源代码存档):ex openssl-1.1.1.tar.gz,我得到这个错误:`

ex openssl-1.1.1.tar.gz                                                                                          
Error: nu::shell::external_command (link)

  × External command failed
     ╭─[/home/ysyltbya/.config/nushell/config.nu:523:1]
 523 │          }
 524 │          else if $file == *.tar.gz {
     ·   ──┬─
     ·     ╰── did you mean 'ls'?
 525 │                  tar xzf $file;
     ╰────
  help: No such file or directory (os error 2)

我不明白出了什么问题。

j9per5c4

j9per5c41#

主要的问题是您仍然在尝试使用Bash模式进行字符串匹配。您可以在Nushell中使用以下两种方法之一来完成此操作:

  • ends-with字符串比较运算符:
if $file ends-with '.tbz2' ...
  • 或正则表达式比较:
if $file =~ '.*\.tbz2' ...

但是,您可能会考虑一种功能性更强/数据驱动/Nushell的方法:

def ex [$file?: string] {
    let archivers = [
        [ pattern         , command              , options       ];
        [ ".tar.bz2"      , "tar"                , "xjf"         ]
        [ ".tar.gz"       , "tar"                , "xzf"         ]
        [ ".bz2"          , "unzip2"             , ""            ]
        [ ".tar.bz2"      , "tar"                , "xjf"         ]
        [ ".rar"          , "unrar"              , ""            ]
        [ ".gz"           , "gunzip"             , ""            ]
        [ ".tar"          , "tar"                , "xf"          ]
        [ ".tbz2"         , "tar"                , "xjf"         ]
        [ ".tgz"          , "tar"                , "xzf"         ]
        [ ".zip"          , "unzip"              , ""            ]
        [ ".Z"            , "uncompress"         , ""            ]
        [ ".7z"           , "7z"                 , "x"           ]
    ]

    if $file == null {
        print -e "No file defined"
    } else if not ($file | path exists) {
        print -e $"Can't find ($file)"
    } else {
        let matchingArchivers = ($archivers | where { |archiver| $file ends-with $archiver.pattern })
        if ($matchingArchivers | length) > 0 {
            let archiver = $matchingArchivers.0
            run-external $archiver.command $archiver.options $file
        } else {
            print -e $"($file) cannot be extracted via ex\(\)"
        }
    }
}

备注:

  • 使用此表单,进行更改和添加要容易得多;更像是Bash的case
  • 我添加了其他缺少的逻辑,如(a)检查文件是否存在,以及(b)检查是否存在匹配的应用程序
  • 修正了unzip命令在rar文件上的使用。可能是我自己在这个过程中引入了一些其他的转录错误!
  • 是的,它确实基于 * 每个 * 可能的匹配进行过滤,而不是caseif/else的正常“短路”行为,但影响很小。
  • 使用找到的 * 第一个 * 匹配项来模拟case/if/else的行为。

相关问题