bash - 为每个匹配项执行一次命令的通配符

标签 bash shell wildcard zsh

备用标题:如何在没有循环或 xargs 的情况下循环。

最近,我转向了 zsh,因为它有很多功能。我很好奇:是否有一个扩展通配符的功能,使得命令对每个匹配项执行一次,而不是一次对所有匹配项执行一次。

例子

命令 ebook-convert input_file output_file [options] 只接受一个输入文件。当我要转换多个文件时,我必须手动多次执行命令或使用循环,例如:

for i in *.epub; do 
    ebook-convert "$i" .mobi
done

我想要的是一个功能类似于循环的通配符,这样我就可以节省几次击键。让所述通配符为 。命令

ebook-convert ⁂.epub .mobi

应该扩展到

ebook-convert 1stMatch.epub .mobi
ebook-convert 2ndMatch.epub .mobi
ebook-convert 3rdMatch.epub .mobi
...

仍然对其他答案感兴趣

我接受了对我有用的答案(感谢 Grisha Levit)。但是,如果您知道其他具有此类功能的 shell,比编写循环更短的替代命令,甚至是使用所需通配符扩展 zsh 的方法,我们将不胜感激。

最佳答案

so that I can save a few keystrokes

好的,假设您输入了

ebook-convert *.epub .mobi

…现在您意识到这是行不通的——您需要编写一个循环。你通常会做什么?大概是这样的:

  • 添加; done 到行尾
  • CtrlA 转到行首
  • 键入 for i in
  • 等等……

这看起来很适合 readline 键盘宏:

让我们根据读取行 commands 来写出这些步骤和常规按键:

end-of-line                    # (start from the end for consistency)
; done                         # type in the loop closing statement
character-search-backward *    # go back to the where the glob is
shell-backward-word            # (in case the glob is in the mid-word)
shell-kill-word                # "cut" the word with the glob
"$i"                           # type the loop variable
beginning-of-line              # go back to the start of the line
for i in                       # type the beginning of the loop opening
yank                           # "paste" the word with the glob
; do                           # type the end of the loop opening

Creating the binding:

For any readline command used above that does not have a key-binding, we need to create one. We also need to create a binding for the new macro that we are creating.

Unless you've already done a lot of readline customization, running the commands below will set the bindings up for the current shell. This uses default bindings like \C-eend-of-line.

bind '"\eB": shell-backward-word'
bind '"\eD": shell-kill-word'

bind '"\C-i": "\C-e; done\e\C-]*\eB\eD \"$i\"\C-afor i in\C-y; do "'

绑定(bind)也可以进入 inputrc用于持久化的文件。

使用快捷方式:

设置之后:

  1. 输入类似的内容

    ebook-convert *.epub .mobi
  2. CtrlI
  3. 该行将转化为

    for i in *.epub; do ebook-convert "$i" .mobi; done

如果你想立即运行命令,你可以修改宏以附加一个\C-j作为最后一次按键,这将触发accept-line(同如同点击 Return)。

关于bash - 为每个匹配项执行一次命令的通配符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42033559/

相关文章:

linux - 如何为此代码制作错误消息

c++ - 当 * 作为参数之一传递时 argc 的值在 c 中调用程序

bash - 如何在 ssh 命令行中使用环境模块?

bash - While 循环在 Bash 中的第一行之后停止读取

linux - 在 systemd 服务中使用用户的 .bashrc

shell - 如何获取更新的记录以及从 RDBMS 表到 Hive 表的增量导入?

具有继承和协变的 Java 泛型

java - java 泛型中的有界通配符

java - Lucene 通配符查询

ruby - 将 YAML 数组转换为 Bash 数组