0

假设/tmp有子目录/test1,,等等,每个里面都有多个文件/test2/test3

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

因此,例如,我必须获取目录名称,其下/tmp将是test1, test2, ... 对于每个子目录,我必须处理其中的文件。

我怎样才能做到这一点?


澄清:

这是我要运行的命令:

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

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

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

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

4

5 回答 5

1

您应该能够使用带有嵌入式 shell 命令的单个 命令:find

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

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

  • 方法是让find匹配目录,然后在每个匹配的目录中,执行一个带有文件处理循环的 shell ( sh -c '<shellCmd>')。
  • 如果不能保证所有子目录都有*.json文件,请将 shell 命令更改为for f in *.json; do [ -f "$f" ] && /tmp/test.py "$f"; done

更新:另外两个考虑;kenorb的回答

  • 默认情况下,find处理输入目录的整个子树。要将匹配限制为直接子目录,请使用-maxdepth 1[1]

    find /PROD -maxdepth 1 -type d ...
    
  • 如前所述,-execdir- 在当前正在处理的目录中运行传递给它的命令 - 不符合 POSIX 标准;您可以通过使用-exec而不是在shellcd命令中包含一个带有手头目录路径 ( {}) 的命令来解决此问题:

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

[1] 严格来说,您可以将-maxdepth选项放在命令行上输入文件路径之后的任何位置find- 作为选项,它不是位置的。但是,除非您将它放在测试(例如)操作(例如)之前,否则GNUfind会发出警告。 -type -exec

于 2015-03-04T16:40:21.587 回答
1

尝试以下用法find

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

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

于 2015-03-04T17:31:26.670 回答
0

您可以像这样使用 bash 的 subshel​​l 功能来做到这一点

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 实例完全一样,只是它稍微更优化一些。

于 2015-03-04T16:30:21.063 回答
0

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

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

甚至使用您的原始find命令:

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

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

于 2015-03-05T23:24:55.100 回答
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 文件。

于 2015-03-05T23:31:51.283 回答