如何在linux中只处理新的(未处理的)文件

时间:2014-05-12 19:18:48

标签: python linux bash

给定一个包含大量小文件(> 1 mio)的目录,可以快速记住哪些文件已经处理过(对于数据库导入)。

我尝试的第一个解决方案是bash脚本:

#find all gz files
for f in $(find $rawdatapath -name '*.gz'); do
    filename=`basename $f`

    #check whether the filename is already contained in the process list
    onlist=`grep $filename $processed_files`
    if [[ -z $onlist ]]
        then
            echo "processing, new: $filename"
            #unzip file and import into mongodb

            #write filename into processed list
            echo $filename #>> $processed_files
    fi
done

对于较小的样本(160k文件),这大约需要8分钟(没有任何处理)

接下来我尝试了一个python脚本:

import os

path = "/home/b2blogin/webapps/mongodb/rawdata/segment_slideproof_testing"
processed_files_file = os.path.join(path,"processed_files.txt")
processed_files = [line.strip() for line in open(processed_files_file)]

with open(processed_files_file, "a") as pff:
  for root, dirs, files in os.walk(path):
      for file in files:
          if file.endswith(".gz"):
              if file not in processed_files:
                  pff.write("%s\n" % file)

这在不到2分钟的时间内完成。

我忽略了一种明显更快的方式吗?

其他解决方案:

  • 由于我使用s3sync下载新文件
  • ,因此将处理过的文件移动到其他位置并不方便
  • 由于文件的时间戳作为其名称的一部分,我可能会考虑依赖它们按顺序处理它们,并仅将名称与“上次处理”日期进行比较
  • 或者我可以跟踪上次处理的时间,并且只处理自那以后修改过的文件。

3 个答案:

答案 0 :(得分:6)

只需使用一套:

import os

path = "/home/b2blogin/webapps/mongodb/rawdata/segment_slideproof_testing"
processed_files_file = os.path.join(path,"processed_files.txt")
processed_files = set(line.strip() for line in open(processed_files_file))

with open(processed_files_file, "a") as pff:
    for root, dirs, files in os.walk(path):
        for file in files:
            if file.endswith(".gz"):
                if file not in processed_files:
                    pff.write("%s\n" % file)

答案 1 :(得分:2)

使用标准命令行实用程序的替代方法:

只需diff一个包含所有文件列表的文件,其中包含一个包含已处理文件列表的文件。

易于尝试,而且应该非常快。

如果您在列表中包含完整时间戳,则可以通过这种方式获取“已更改”文件。

答案 2 :(得分:1)

如果文件在处理后未被修改,则一个选项是记住最新处理的文件,然后使用find的{​​{1}}选项检索尚未处理的文件。

-newer

其中process.sh看起来像

find $rawdatapath -name '*.gz' -newer $(<latest_file) -exec process.sh {} \;

这是未经测试的。在考虑实施此策略之前,请注意不必要的副作用。

如果可以使用hacky / quick&n&#cr#解决方案,一个时髦的替代方法是对文件权限中的状态(已处理或未处理)进行编码,例如组读权限位。假设您的#!/bin/env bash echo "processing, new: $1" #unzip file and import into mongodb echo $1 > latest_file umask,以便新创建的文件具有022权限,请在处理完文件后将权限更改为644并使用600&# 39; s find选项,用于检索尚未处理的文件。

-perm

其中process.sh看起来像

find $rawdatapath -name '*.gz' -perm 644 -exec process.sh {} \;

这是未经测试的。在考虑实施此策略之前,请注意不必要的副作用。