这个问题真的很简单,我知道如何用Python做到这一点,但我想在Linux shell(bash)中做到这一点。
我有一个主文件夹Dataset
,其中有多个子文件夹Dataset_FinalFolder_0_10
,一直到Dataset_FinalFolder_1090_1100
为止,每个子文件夹包含10个文件。
我想在每个文件上运行一个程序。在Python中,我可以使用类似以下内容的方法:
for folder in /path/to/folders:
for file in folder:
run program
有什么办法可以在Shell / bash中模仿吗?
我有用于更直接迭代的这段代码:
for i in /path/to/folder/*;
do program "$i";
done
预先感谢
答案 0 :(得分:2)
如果您确定没有文件夹混入文件,也没有文件夹混入文件:
for folder in /path/to/Dataset/*; do
for file in "$folder"/*; do
program "$file"
done
done
或者,可以给出多个*
:
for file in /path/to/Dataset/*/*; do
program "$file"
done
如果不确定文件夹的内容,find
可以为您提供帮助。此示例仅在给定文件夹的第一级子目录中选择文件,并且每个文件的xargs调用程序:
find /path/to/Dataset/ -mindepth 2 -maxdepth 2 -type f |\
xargs -n1 program
如果.../*/*/*/...
可以扩展到大量路径,则find方法可能也很有用。在Linux上,命令行长度限制显示为:
getconf ARG_MAX
在我的机器上是2 ^ 21(约200万)个字符。因此,限制很高,但是值得您记住的是一个限制。
答案 1 :(得分:1)
从Linux的角度来看,您必须提防适当转义的空格,换行等,这些可能会有点时髦。为什么不这样做有很多参考-参见
http://mywiki.wooledge.org/ParsingLs
还有
https://unix.stackexchange.com/questions/128985/why-not-parse-ls-and-what-do-to-instead
那是...
您始终可以通过find
选项使用-exec
命令-
find /path/to/top/level -type f -exec /path/to/processing/program {} \;
要求末尾的\;
表示执行程序的结束
答案 2 :(得分:0)
除非您有太多的文件以至于遇到“参数列表过长”错误,否则您不需要在Python或Shell中使用嵌套循环。
for file in /path/to/folders/*/*; do
program "$file"
done
这等效于Python代码
from glob import glob
from subprocess import run
for file in glob('/path/to/folders/*/*'):
run(['program', file])
当然,如果program
完全能胜任写作,那么您可以简单地做到
program /path/to/folders/*/*
这对应于
run(['program'] + glob('/path/to/folders/*/*')
如果program
接受文件名参数列表,但是您确实需要分拆命令行以避免“参数列表太长”错误,请尝试
printf '%s\0' /path/to/folders/*/* |
xargs -r0 program
(零终止符模式是GNU find
扩展名,-r
选项也是如此。)
答案 3 :(得分:-2)
for dir in ./* ./**/* # list directories in the current directory
do
python $dir
done
./*是dir中的文件,。/ ** / *是子文件夹中的文件。
确保目录中只有python文件,它将运行该目录中的所有文件
实际上我已经在这里回答了 Iterate shell script over list of subdirectories