从这么多文件的开头删除数字的最快方法是什么?
What is the fastest way to remove a number from the beginning of so many files?
我有 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
for file in dir/*; do
cut -f2 -d ',' "$file" > $TMP && mv $TMP "$file"
done
值得一提的是,与使用单独的文件相比,就地做事通常需要更长的时间。我尝试了您的 sed 命令,但从原地切换到临时文件。总时间从 26 秒减少到 9 秒。
我会使用 GNU awk
(利用 -i inplace
文件编辑),,
作为字段分隔符,没有昂贵的正则表达式操作:
awk -F, -i inplace '{print }' file.txt
例如,如果文件名有一个共同的前缀,如 file
,您可以使用 shell globbing:
awk -F, -i inplace '{print }' file*
awk
将在应用就地修改时将每个文件视为不同的参数。
作为旁注,您可以直接 运行 shell 中的 shell 命令,而不是将其包装在 os.system()
中,这是不安全的,顺便说一句,在赞成 subprocess
.
您可以利用您的多核系统,以及其他用户关于更快处理特定文件的提示。
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
也许 writerows
部分可以通过使用 map
& operator.itemgetter
删除内部循环来更快:
csv.writer(fw).writerows(map(operator.itemgetter(1),csv.reader(fr)))
还有:
- 它在所有系统上都是可移植的,包括 windows 没有安装 MSYS
- 在避免破坏输入的问题的情况下异常停止
- 临时文件是故意在同一个文件系统中创建的,因此删除+重命名非常快(而不是将临时文件移动到跨文件系统输入,这需要
shutil.move
并且会复制数据)
我有 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
for file in dir/*; do
cut -f2 -d ',' "$file" > $TMP && mv $TMP "$file"
done
值得一提的是,与使用单独的文件相比,就地做事通常需要更长的时间。我尝试了您的 sed 命令,但从原地切换到临时文件。总时间从 26 秒减少到 9 秒。
我会使用 GNU awk
(利用 -i inplace
文件编辑),,
作为字段分隔符,没有昂贵的正则表达式操作:
awk -F, -i inplace '{print }' file.txt
例如,如果文件名有一个共同的前缀,如 file
,您可以使用 shell globbing:
awk -F, -i inplace '{print }' file*
awk
将在应用就地修改时将每个文件视为不同的参数。
作为旁注,您可以直接 运行 shell 中的 shell 命令,而不是将其包装在 os.system()
中,这是不安全的,顺便说一句,在赞成 subprocess
.
您可以利用您的多核系统,以及其他用户关于更快处理特定文件的提示。
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
也许 writerows
部分可以通过使用 map
& operator.itemgetter
删除内部循环来更快:
csv.writer(fw).writerows(map(operator.itemgetter(1),csv.reader(fr)))
还有:
- 它在所有系统上都是可移植的,包括 windows 没有安装 MSYS
- 在避免破坏输入的问题的情况下异常停止
- 临时文件是故意在同一个文件系统中创建的,因此删除+重命名非常快(而不是将临时文件移动到跨文件系统输入,这需要
shutil.move
并且会复制数据)