在每个目录中查找子目录和进程文件的名称
Find the name of subdirectories and process files in each
假设 /tmp
有子目录 /test1
、/test2
、/test3
等等,
每个里面都有多个文件。
我必须 运行 while
循环或 for
循环来查找目录的名称(在本例中为 /test1
、/test2
、 ...)
和 运行 一个处理每个目录内所有文件的命令。
所以,例如,
我必须获取 /tmp
下的目录名称,这将是 test1
、test2
、...
对于每个子目录,我必须处理其中的文件。
我该怎么做?
澄清:
这是我想要的命令 运行:
find /PROD/140725_D0/ -name "*.json" -exec /tmp/test.py {} \;
其中 140725_D0
是要处理的 一个 子目录的示例 - 有多个,名称不同。
因此,通过使用 for
或 while
循环,我想找到所有子目录和 运行 每个文件的命令。
for
或 while
循环应该迭代地替换上面 find 命令中的硬编码名称 140725_D0
。
您可以像这样使用 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 的另一个实例完全一样,只是它稍微更优化。
您应该能够使用 单个 find
命令和 嵌入式 shell 命令:
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
更新:还有两个注意事项;向 致敬:
默认情况下,find
处理输入目录的整个子树。要限制与 直接 子目录的匹配,请使用 -maxdepth 1
[1]:
find /PROD -maxdepth 1 -type d ...
如前所述,-execdir
- 在当前正在处理的目录中运行传递给它的命令 - 不符合 POSIX;您可以通过使用 -exec
来解决这个问题,并在 shell命令:
find /PROD -type d -exec sh -c 'cd "{}" && for f in *.json; do /tmp/test.py "$f"; done' \;
[1] 严格来说,您可以将 -maxdepth
选项 放在 find
命令的输入文件路径 之后的任何位置行 - 作为一个 选项 ,它不是位置性的。但是,GNU find
会发出警告,除非你把它放在 before tests (比如 -type
) andactions(比如-exec
).
尝试 find
的以下用法:
find . -type d -exec sh -c 'cd "{}" && echo Do some stuff for {}, files are: $(ls *.*)' ';'
如果您想限制目录级别,请使用 -maxdepth
。
您也可以简单地要求 shell 扩展您需要的 directories/files,例如使用命令 xargs
:
echo /PROD/*/*.json | xargs -n 1 /tmp/test.py
甚至使用您原来的 find
命令:
find /PROD/* -name "*.json" -exec /tmp/test.py {} \;
这两个命令将处理包含在 /PROD
.
的任何子目录中的所有 JSON 文件
另一个解决方案是稍微更改脚本中的 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 文件。
假设 /tmp
有子目录 /test1
、/test2
、/test3
等等,
每个里面都有多个文件。
我必须 运行 while
循环或 for
循环来查找目录的名称(在本例中为 /test1
、/test2
、 ...)
和 运行 一个处理每个目录内所有文件的命令。
所以,例如,
我必须获取 /tmp
下的目录名称,这将是 test1
、test2
、...
对于每个子目录,我必须处理其中的文件。
我该怎么做?
澄清:
这是我想要的命令 运行:
find /PROD/140725_D0/ -name "*.json" -exec /tmp/test.py {} \;
其中 140725_D0
是要处理的 一个 子目录的示例 - 有多个,名称不同。
因此,通过使用 for
或 while
循环,我想找到所有子目录和 运行 每个文件的命令。
for
或 while
循环应该迭代地替换上面 find 命令中的硬编码名称 140725_D0
。
您可以像这样使用 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 的另一个实例完全一样,只是它稍微更优化。
您应该能够使用 单个 find
命令和 嵌入式 shell 命令:
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
更新:还有两个注意事项;向
默认情况下,
find
处理输入目录的整个子树。要限制与 直接 子目录的匹配,请使用-maxdepth 1
[1]:find /PROD -maxdepth 1 -type d ...
如前所述,
-execdir
- 在当前正在处理的目录中运行传递给它的命令 - 不符合 POSIX;您可以通过使用-exec
来解决这个问题,并在 shell命令:find /PROD -type d -exec sh -c 'cd "{}" && for f in *.json; do /tmp/test.py "$f"; done' \;
[1] 严格来说,您可以将 -maxdepth
选项 放在 find
命令的输入文件路径 之后的任何位置行 - 作为一个 选项 ,它不是位置性的。但是,GNU find
会发出警告,除非你把它放在 before tests (比如 -type
) andactions(比如-exec
).
尝试 find
的以下用法:
find . -type d -exec sh -c 'cd "{}" && echo Do some stuff for {}, files are: $(ls *.*)' ';'
如果您想限制目录级别,请使用 -maxdepth
。
您也可以简单地要求 shell 扩展您需要的 directories/files,例如使用命令 xargs
:
echo /PROD/*/*.json | xargs -n 1 /tmp/test.py
甚至使用您原来的 find
命令:
find /PROD/* -name "*.json" -exec /tmp/test.py {} \;
这两个命令将处理包含在 /PROD
.
另一个解决方案是稍微更改脚本中的 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 文件。