我经常有一个处理一个文件的命令,我想在目录中的每个文件上运行它.有没有内置的方法来做到这一点?
例如,假设我有一个程序data输出关于文件的重要数字:
./data foo
137
./data bar
42
Run Code Online (Sandbox Code Playgroud)
我想以某种方式在目录中的每个文件上运行它,如下所示:
map data `ls *`
ls * | map data
Run Code Online (Sandbox Code Playgroud)
产生这样的输出:
foo: 137
bar: 42
Run Code Online (Sandbox Code Playgroud)
Dan*_*ley 15
如果你只是想执行你data的一堆文件的程序,最简单的/最不复杂的方法是使用-exec在find.
假设您要data在当前目录(和子目录)中的所有txt文件上执行.这就是你所需要的:
find . -name "*.txt" -exec data {} \;
Run Code Online (Sandbox Code Playgroud)
如果要将其限制为当前目录,可以执行以下操作:
find . -maxdepth 1 -name "*.txt" -exec data {} \;
Run Code Online (Sandbox Code Playgroud)
有很多选择find.
如果您只想在每个文件上运行命令,可以执行以下操作:
for i in *; do data "$i"; done
Run Code Online (Sandbox Code Playgroud)
如果您还希望显示当前正在处理的文件名,那么您可以使用:
for i in *; do echo -n "$i: "; data "$i"; done
Run Code Online (Sandbox Code Playgroud)
它看起来像你想要的xargs:
find . --maxdepth 1 | xargs -d'\n' data
Run Code Online (Sandbox Code Playgroud)
要首先打印每个命令,它会变得更复杂:
find . --maxdepth 1 | xargs -d'\n' -I {} bash -c "echo {}; data {}"
Run Code Online (Sandbox Code Playgroud)
你应该避免解析ls:
find . -maxdepth 1 | while read -r file; do do_something_with "$file"; done
Run Code Online (Sandbox Code Playgroud)
要么
while read -r file; do do_something_with "$file"; done < <(find . -maxdepth 1)
Run Code Online (Sandbox Code Playgroud)
后者不会在while循环中创建子shell.