在每个子目录中找到子目录和进程文件的名称

时间:2015-03-04 16:25:35

标签: linux bash shell gnu-findutils

假设/tmp包含子目录/test1/test2/test3等等, 并且每个文件都有多个文件。

我必须运行while循环或for循环来查找目录的名称(在本例中为/test1/test2,...) 并运行一个命令来处理每个目录中的所有文件。

所以,例如, 我必须在/tmp下获取目录名称test1test2,... 对于每个子目录,我必须处理其中的文件。

我该怎么做?


澄清:

这是我想要运行的命令:

find /PROD/140725_D0/ -name "*.json" -exec /tmp/test.py {} \;

其中140725_D0是要处理的一个子目录的示例 - 有多个,具有不同的名称。

因此,通过使用forwhile循环,我想查找所有子目录并对每个子目录中的文件运行命令。

forwhile循环应迭代替换上面find命令中的硬编码名称140725_D0

5 个答案:

答案 0 :(得分:1)

您应该能够使用嵌入式shell命令执行 find命令:

find /PROD -type d -execdir sh -c 'for f in *.json; do /tmp/test.py "$f"; done' \;

注意:-execdir不符合POSIX标准,但find的BSD(OSX)和GNU(Linux)版本支持它;请参阅下面的POSIX替代方案。

  • 方法是让find匹配目录,然后,在每个匹配的目录中,执行带有文件处理循环的shell ({{ 1}})。
  • 如果并非所有子目录都保证有sh -c '<shellCmd>'个文件,请将shell命令更改为*.json

更新:还有两个注意事项;将小费改为kenorb's answer

  • 默认情况下,for f in *.json; do [ -f "$f" ] && /tmp/test.py "$f"; done处理输入目录的整个子树。要限制与 immediate 子目录的匹配,请使用find [1]

    -maxdepth 1
  • 如上所述,find /PROD -maxdepth 1 -type d ... - 运行在当前正在处理的目录中传递给它的命令 - 不符合POSIX;您可以通过使用-execdir代替并在 shell 命令中包含-exec命令和手头的目录路径(cd)来解决此问题:

    {}

[1]严格地说,您可以将find /PROD -type d -exec sh -c 'cd "{}" && for f in *.json; do /tmp/test.py "$f"; done' \; 选项放在-maxdepth命令行上的输入文件路径之后的任何位置 - 作为选项,它不是位置的。但是,GNU find会发出警告,除非您在 测试之前将其放置(例如find < em> actions (例如-type)。

答案 1 :(得分:1)

请尝试使用find

find . -type d -exec sh -c 'cd "{}" && echo Do some stuff for {}, files are: $(ls *.*)' ';'

如果您想限制目录级别,请使用-maxdepth

答案 2 :(得分:0)

你可以使用bash的子shell功能来实现这一点

for i in /tmp/test*; do
  # don't do anything if there's no /test directory in /tmp
  [ "$i" != "/tmp/test*" ] || continue

  for j in $i/*.json; do
    # don't do anything if there's nothing to run
    [ "$j" != "$i/*.json" ] || continue

    (cd $i && ./file_to_run)
  done
done

当您在()中包装命令时,它会启动子shell以运行该命令。子shell就像启动另一个bash实例一样,除了它稍微更优化。

答案 3 :(得分:0)

您也可以简单地要求shell扩展您需要的目录/文件,例如使用命令xargs

echo /PROD/*/*.json | xargs -n 1 /tmp/test.py

甚至使用原始find命令:

find /PROD/* -name "*.json" -exec /tmp/test.py {} \;

两个命令都将处理包含在/PROD的任何子目录中的所有JSON文件。

答案 4 :(得分:0)

另一种解决方案是稍微更改脚本中的Python代码,以便接受和处理多个文件。 例如,如果您的脚本包含以下内容:

def process(fname):
    print 'Processing file', fname

if __name__ == '__main__':
    import sys
    process(sys.argv[1])

你可以用:

替换最后一行
    for fname in sys.argv[1:]:
        process(fname)

经过这个简单的修改,你可以这样调用你的脚本:

/tmp/test.py /PROD/*/*.json

让它处理所有想要的JSON文件。