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

Regex 从这么多文件的开头删除数字的最快方法是什么?,regex,bash,performance,shell,text-processing,Regex,Bash,Performance,Shell,Text Processing,我有1000个文件,每个文件有一百万行。每行具有以下形式: a number,a text 我想删除每个文件每行开头的所有数字。包括 例如: 14671823,aboasdyflj -> aboasdyflj 我正在做的是: os.system("sed -i -- 's/^.*,//g' data/*") 它工作正常,但需要花费大量的时间 最快的方法是什么 我正在用python编写代码。这要快得多: cut -f2 -d ',' data.txt > tmp.txt &

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

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

例如:

14671823,aboasdyflj -> aboasdyflj
我正在做的是:

os.system("sed -i -- 's/^.*,//g' data/*")
它工作正常,但需要花费大量的时间

最快的方法是什么

我正在用python编写代码。

这要快得多:

cut -f2 -d ',' data.txt > tmp.txt && mv tmp.txt data.txt
在一个有1100万行的文件上,只花了不到一秒钟的时间

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

TMP=/pathto/tmpfile
对于dir/*中的文件;做
剪切-f2-d',“$file”>$TMP&&mv$TMP“$file”
完成

值得一提的是,与使用单独的文件相比,在适当的位置执行内容通常需要更长的时间。我尝试了你的sed命令,但从原地切换到临时文件。总时间从26秒下降到9秒。

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

例如,如果文件名有一个公共前缀,如
file
,则可以使用shell globbing:

awk -F, -i inplace '{print $2}' file*
awk
在应用就地修改时,会将每个文件视为不同的参数



顺便说一句,您可以直接在shell中运行shell命令,而不是将其包装在
os.system()
中,这是不安全的,而且不推荐使用
子进程,您可以利用您的多核系统,以及其他用户关于更快处理特定文件的提示

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!"

这可能相当快&原生python。减少循环并使用在大多数实现中编译的
csv.reader
csv.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
通过使用
map
操作符,也许
writerows
部分可以更快。itemgetter
删除内部循环:

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

  • 它在所有系统上都是可移植的,包括未安装MSYS的windows
  • 在避免破坏输入的情况下,它会异常停止
  • 临时文件是特意在同一文件系统中创建的,因此删除+重命名速度非常快(与跨文件系统将临时文件移动到输入端不同,这需要
    shutil.move
    &复制数据)

我不能说最好的方法是什么,但就正则表达式而言,您可以减少所采取的步骤数量。改用
^[^,]*,
。更好的方法是,使用
^\d+,
我不确定我是否会将调用外部程序称为“用Python编码”,但最终,这可能是最快的,除非您可以在
sed
中调整匹配以减少工作量。。。除此之外,这将取决于您的系统负载和驱动器的速度。这不是用python编写的。用python编写可能会更慢。
“sed-i--'s/^.*,//'data/*”
会稍微快一点(去掉
g
)第二个字段中有数字吗?你能用python 3编辑你的答案吗?我想将来读这篇文章的大多数人都不会使用python2。多重处理真的有什么不同吗?我怀疑IO是这里要求最高的部分。
[p.start()表示进程中的p]
是非音速的:不要将listcomps用作sideeffects@klutt:无需麻烦进行多处理。多线程的作用与系统创建新进程的作用是一样的。@Jean-Françoisfare是的,但无论哪种方式,它似乎都增加了复杂性,甚至可能更慢。我不明白你为什么不做
cut-f2-d',“$file”>tmp.txt&&mv tmp.txt“$file”
@yukashimahuksay你可以这么做,但是如果您有一个实际名称为
tmp.txt
的文件怎么办?如果您希望它以这种方式工作,那么只需将第一行更改为
TMP=TMP.txt
或其他内容。
csv.writer(fw).writerows(map(operator.itemgetter(1),csv.reader(fr)))