从这么多文件的开头删除数字的最快方法是什么?

问题描述 投票:2回答:4

我有1000个文件,每个文件有一百万行。每一行都有以下形式:

a number,a text

我想从每个文件的每一行的开头删除所有数字。包括 ,

例:

14671823,aboasdyflj -> aboasdyflj

我在做的是:

os.system("sed -i -- 's/^.*,//g' data/*")

它工作正常,但需要花费大量的时间。

最快的方法是什么?

我在python中编码。

regex bash performance shell text-processing
4个回答
5
投票

这要快得多:

cut -f2 -d ',' data.txt > tmp.txt && mv tmp.txt data.txt

在一个有1100万行的文件上花了不到一秒钟。

要在目录中的多个文件上使用它,请使用:

TMP=/pathto/tmpfile
for file in dir/*; do
    cut -f2 -d ',' "$file" > $TMP && mv $TMP "$file"
done

值得一提的是,通常需要花费更长的时间才能使用单独的文件。我尝试了你的sed命令,但从原地切换到临时文件。总时间从26秒下降到9秒。


2
投票

我会使用GNU awk(利用文件的-i inplace编辑)和,作为字段分隔符,没有昂贵的正则表达式操作:

awk -F, -i inplace '{print $2}' file.txt

例如,如果文件名具有像file这样的公共前缀,则可以使用shell globbing:

awk -F, -i inplace '{print $2}' file*

在应用就地修改时,awk会将每个文件视为不同的参数。


作为旁注,您可以直接在shell中运行shell命令,而不是将其包装在os.system()中,这是不安全的,不推荐使用BTW而不是subprocess


2
投票

这可能是非常快和原生的python。减少循环并使用在大多数实现中编译的csv.readercsv.writer

import csv,os,glob
for f1 in glob.glob("*.txt"):
    f2 = f1+".new"
    with open(f1) as fr, open(f2,"w",newline="") as fw:
        csv.writer(fw).writerows(x[1] for x in csv.reader(fr))
    os.remove(f1)
    os.rename(f2,f1)  # move back the newfile into the old one

也许writerows部分可以通过使用mapoperator.itemgetter删除内循环更快:

csv.writer(fw).writerows(map(operator.itemgetter(1),csv.reader(fr)))

也:

  • 它可以在所有系统上移植,包括没有安装MSYS的窗口
  • 如果问题避免破坏输入,它会异常停止
  • 临时文件是故意在相同的文件系统中创建的,因此删除+重命名是超快的(而不是将临时文件移动到跨文件系统的输入,这需要shutil.move并将复制数据)

1
投票

您可以利用您的多核系统以及其他用户更快地处理特定文件的提示。

FILES = ['a', 'b', 'c', 'd']
CORES = 4

q = multiprocessing.Queue(len(FILES))

for f in FILES:
    q.put(f)

def handler(q, i):
    while True:
        try:
            f = q.get(block=False)
        except Queue.Empty:
            return
        os.system("cut -f2 -d ',' {f} > tmp{i} && mv tmp{i} {f}".format(**locals()))

processes = [multiprocessing.Process(target=handler, args=(q, i)) for i in range(CORES)]

[p.start() for p in processes]
[p.join() for p in processes]

print "Done!"
© www.soinside.com 2019 - 2024. All rights reserved.