【问题标题】:How to `command file.txt OR another_file.txt` in CLI (bash/zsh)如何在 CLI (bash/zsh) 中“命令 file.txt 或 another_file.txt”
【发布时间】:2020-01-07 12:07:02
【问题描述】:

是否可以使用file.txt 作为参数运行命令,或者如果file.txt 不存在,则使用another_file.txt 运行命令?

为了使我的要求更现实,我想默认使用工作区文件运行 VSCode,或者,如果工作区文件不存在,则使用 .(当前文件夹),类似:

code *.code-workspace OR .

如果*.code-workspace存在,那么command应该等价于code *.code-workspace,否则commend应该等价于code .

可以在bashzsh 中使用吗? (我正在使用zsh + oh-my-zsh

【问题讨论】:

  • 是的,有可能。你试过什么?然后编辑您的问题,请发布您尝试过的内容。为什么它不起作用?所以你的问题是如何做到这一点或如何以“优雅的方式”做到这一点?
  • 我用 if-else 尝试了自定义函数,它可以工作。但我想知道是否有任何优雅的方式来执行相同的操作?
  • 如果当前目录下有多个工作区文件,你会怎么做?
  • @tom-fenech 在第一场比赛中运行code
  • 如果只是两个文件,我想不出一个看起来特别短的解决方案。如果我经常需要这个功能,我只需编写一个 shell 脚本(或函数),它会迭代其参数并将第一个参数打印到与现有文件对应的标准输出。编写此脚本后,您不需要任何复杂的if 逻辑。

标签: bash terminal command-line-interface zsh


【解决方案1】:

在 bash 中,如果没有匹配项,您可以使用 nullglob 将通配符(如 *)扩展为空。然后将所有内容放入数组并检索第一个条目。请注意,$array 与第一个数组条目 ${array[0]} 相同。

#! /bin/bash
shopt -s nullglob
files=(*.code-workspace .)
code "$files"

如果有以.code-workspace 结尾的文件,则上面的代码以code firstMatchOf.code-workspace 开头,如果没有这样的文件,则以. 开头。

对于zsh,您可以通过将shopt -s nullglob 替换为setopt null_glob 来执行相同的操作。

请注意,上述方法仅适用于通配符。即使a 不存在,files=(a b); code "$files" 也会调用code a。在这里,您可以改用以下函数,它应该适用于所有情况:

#! /bin/sh
firstExisting() {
    set -- "$@" . # ensure termination 
    while ! [ -e "$1" ]; do
        shift
    done
    printf %s\\n "$1"
}

使用示例:

code "$(firstExisting *.code-workspace .)"

或者只是

code "$(firstExisting *.code-workspace)"

.... 是默认值,以防不存在任何参数。 shopt -s nullglob 这里不需要。

【讨论】:

  • @LimonMonte 是的,shoptbash 的东西。我认为zshsetopt null_glob。无论如何,第二种方法应该适用于所有 POSIX shell,也适用于非通配符。
  • [ -a "$1" ] 那个-a 有点奇怪,你的意思是-f-r 对吧?
  • -a 是一个非标准的bash 扩展,相当于-e
  • 糟糕。感谢 KamilCuk 和 Chepner 指出这一点。我将脚本更正为符合 POSIX 标准。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-16
  • 2020-02-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多