【问题标题】:Bash vs. Zsh, git grep works in a bash for loop but not a zsh for loop?Bash vs. Zsh,git grep 在 bash for 循环中工作,但不是 zsh for 循环?
【发布时间】:2016-09-09 18:01:47
【问题描述】:

以下内容在 bash 中有效,但在 zsh 中无效,我不确定原因:

user@machine:~/some_git_repo$ for i in $(ls ./conf); do git --no-pager grep $i ; done

zsh shell 会为./conf 中的每个文件生成以下结果

fatal: command line, 'some_file_name.xml': Unmatched [ or [^

【问题讨论】:

  • 在 bash 中这样做也不安全。

标签: bash zsh


【解决方案1】:

您根本不应该在这里使用命令替换。相反,请使用 glob -- 并查看 Why you shouldn't parse the output of ls(1)。

# this works reliably in both bash and zsh
for i in ./conf/*; do git --no-pager grep -F -e "${i##*/}"; done

注意grep -F 的使用——这意味着您的参数被视为文字字符串,而不是正则表达式,因此您不能使用无效的正则表达式语法的文件名。

【讨论】:

  • 而zsh就是zsh,你可以直接写$i:t来获取文件名。
  • @chepner,当然。我的目标是在这里找到一个便携的答案,既要在知识方面保持在我的舒适区域内,又要在便携选项可用时避免鼓励特定于 zsh 的习惯。
  • 如果$(...) 解析为单个字符串,为什么for i in $(ls ./conf); do echo "$i 1" ; done 会正确输出./conf 导向器中带有`1` 的每个文件名?
  • @rudolph9,首先——尝试创建带有空格的文件名,或者更好的是,运行touch 'conf/foo * bar',并观察现有命令的输出。其次,请给我一分钟时间来回顾一下 zsh 的规则——一般情况下它不会默认进行字符串拆分,但for 循环中的命令替换可能会有例外。
  • 参数扩展不会进行分词,但命令替换仍然可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-21
  • 2015-09-23
  • 1970-01-01
  • 1970-01-01
  • 2018-01-05
  • 2018-02-23
相关资源
最近更新 更多