Shell脚本因目录中的大量文件而失败

时间:2012-07-06 13:18:46

标签: bash sh

os:aix,shell:bsh

我在目录中有大约20k的文件,这些文件名为filename.pdf.marker和filename.pdf,我们使用以下代码段复制目录内容

ls ${WORKING_DIR}/*.pdf.marker 2> /dev/null | while read FILEMARKER;
do
    FILENAME=${WORKING_DIR}/$(basename ${FILEMARKER} .marker)
        mv ${FILENAME} ${LOG_DIR}/.  
        mv ${FILENAME}.marker ${LOG_DIR}/.  
    done   

但问题是并非所有文件都被复制,因为 ls 没有返回工作目录中的完整文件列表,因为文件列表太长了。

你可以给我一些建议,如何在不删除循环的情况下升级脚本吗?

THX

5 个答案:

答案 0 :(得分:4)

改为使用shell glob。例如:

for file in ${WORKING_DIR}/*.pdf.marker; do
    : # do something with "$file"
done

答案 1 :(得分:1)

尝试使用find代替ls

find ${WORKING_DIR} -name \*.pdf.marker | while read FILENAME; do
  ...
done

我故意忽略文件名中空格的可能性,以保持简单。

答案 2 :(得分:0)

我不想从CodeGnome中窃取正确的答案,但要明确会发生什么:ls "$WORKING_DIR"/*.pdf.marker会导致新的流程的shell分叉,其中包含#的过程映像ls num_matching_files参数(与Windows不同,其中每个命令都必须包含自己的globbing代码,在Unix上,在命令被调用之前,glob会被 shell 扩展)。

大多数(如果不是所有)系统都有关于命令行长度/参数数量的限制,你刚刚在这里遇到了困难(因为在你的情况下#num_matching_files是20000)

答案 3 :(得分:-1)

如果文件列表太长,

globs会失败。而不是glob,过滤结果:

ls ${WORKING_DIR} | grep '\.pdf\.marker$'  | while read FILEMARKER
do
    ...
done

强制性免责声明:如果您的文件名包含特殊字符(例如任何空格),则会失败。

答案 4 :(得分:-2)

尝试关闭ls-f-U的排序,我认为),或使用其他程序,例如find