对每个文件运行一个命令,使用取决于文件名的标志参数

Nat*_*iel 7 shell find

假设我有一个文件夹,其中包含名称如下的文件

file1.txt
file2.txt
file2.txt
Run Code Online (Sandbox Code Playgroud)

等我想对他们每个人运行一个命令,如下所示:

mycommand file1.txt -o file1-processed.txt
mycommand file2.txt -o file2-processed.txt
mycommand file3.txt -o file3-processed.txt
Run Code Online (Sandbox Code Playgroud)

等等。

这个网站上有几个类似的问题 - 不同的是我想将-processed测试插入文件名的中间,在扩展名之前。

它似乎find应该是这项工作的工具。如果不是为了-o国旗我可以做

find *.txt -exec mycommand "{}" ";"
Run Code Online (Sandbox Code Playgroud)

但是,{}语法给出了整个文件名,例如file1.txt等,所以我不能-processed在文件名及其扩展名之间添加“ ”。使用简单的 bashfor循环也存在类似的问题。

是否有一种简单的方法来完成此任务,使用find或以其他方式?

use*_*316 25

如果要处理的所有文件都在同一个文件夹中,则不需要使用find,并且可以使用本机 shell globbing。

for foo in *.txt ; do
  mycommand "${foo}" -o "${foo%.txt}-processed.txt"
done
Run Code Online (Sandbox Code Playgroud)

shell 惯用法从 的值中${foo%bar}删除与模式匹配的最小后缀字符串,在本例中为扩展名,因此我们可以将其替换为您想要的后缀。barfoo.txt


Kla*_* Š. 6

如果你写一个脚本中的各种系统和便携性运行是一个问题,那么没有什么比for循环和${var%sfx}user1404316的答案。

但是,如果您正在寻找一种在您自己的系统上执行类似操作的便捷方法,那么我衷心推荐GNU Parallel,它基本上xargs是类固醇。这是您的特定任务的解决方案:

parallel mycommand {} -o {.}-processed.txt ::: *.txt
Run Code Online (Sandbox Code Playgroud)

它将获取一个字符串列表:::(shell 将扩展*.txt为匹配文件名的列表)并mycommand {} -o {.}-processed.txt为每个字符串运行,替换{}为输入字符串(就像xargs)和{.}没有扩展名的文件名。

您可以通过stdin( xargs -way)提供输入字符串列表,将其与find或配对locate,但我很少需要比zsh的扩展globs多的东西。

查看GNU Parallel 教程以了解它可以做什么。我一直使用它进行批量转换,将档案提取到 sudirectories 等。