Python从文件

问题描述:

删除“一对多”行,我试图从一个文件的方式,如Python从文件

./foo.py FILENAME.TXT 4 5 2919

删除蟒蛇具体的行号其中4 5和2919是行号

我所试图做的是:

for i in range(len(sys.argv)): 
    if i>1: # Avoiding sys.argv[0,1] 
     newlist.append(int(sys.argv[i])) 

然后:

count=0 

generic_loop{ 
    bar=file.readline() 
    count+=1 
    if not count in newlist: 
     print bar 
} 

它打印在原始文件中的所有行(之间的空格)

+2

什么是generic_loop?如果你发布了真实的代码而不是假的代码会更好。 – 2013-05-06 02:08:45

+0

我担心它可能看起来太具体,所以我这样做。 – Mansueli 2013-05-06 03:08:46

+1

我也鼓励你使用['argparse'](http://docs.python.org/dev/library/argparse.html)。如果您使用'type = int'和'nargs ='*'',则不必处理'sys.argv',并且您可以免费获得出色的错误/使用信息。 – Felipe 2013-05-06 10:41:05

你可以尝试这样的事情:

import sys 
import os 
filename= sys.argv[1] 
lines = [int(x) for x in sys.argv[2:]] 

#open two files one for reading and one for writing 

with open(filename) as f,open("newfile","w") as f2: 

#use enumerate to get the line as well as line number, use enumerate(f,1) to start index from 1 
    for i,line in enumerate(f): 
     if i not in lines:  #`if i not in lines` is more clear than `if not i in line` 
      f2.write(line) 
os.rename("newfile",filename) #rename the newfile to original one  

注意,对于临时文件的生成,最好使用tempfile模块。

+1

要小心;这不是线程或过程安全的;如果多个进程并行运行这个程序,他们可能会覆盖临时文件。改为使用['tempfile'模块](http://docs.python.org/dev/library/tempfile.html)。 – phihag 2013-05-06 02:41:04

+0

@phpha感谢您的建议,我从来没有听说过'tempfile'。 – 2013-05-06 02:51:14

您可以使用enumerate来确定行号:

import sys 
exclude = set(map(int, sys.argv[2:])) 
with open(sys.argv[1]) as f: 
    for num,line in enumerate(f, start=1): 
     if num not in exclude: 
      sys.stdout.write(line) 

您可以删除start=1,如果你开始计数为0.在上面的代码中,行编号以1开头:

$ python3 so-linenumber.py so-linenumber.py 2 4 5 
import sys 
with open(sys.argv[1], 'r') as f: 
      sys.stdout.write(line) 

如果要将内容写入文件本身,请将其写入temporary file而不是sys.stdout,然后将rename即写入原始文件名(或在命令行上使用sponge),如下所示:

import os 
import sys 
from tempfile import NamedTemporaryFile 
exclude = set(map(int, sys.argv[2:])) 
with NamedTemporaryFile('w', delete=False) as outf: 
    with open(sys.argv[1]) as inf: 
     outf.writelines(line for n,line in enumerate(inf, 1) if n not in exclude) 
    os.rename(outf.name, sys.argv[1]) 
+0

尽管很好的使用了'tempfile','fileinput'支持简单的就地编辑,就像在更简洁的代码中一样 – jamylak 2013-05-06 10:33:16

import sys 
# assumes line numbering starts with 1 
# enumerate() starts with zero, so we subtract 1 from each line argument 
omitlines = set(int(arg)-1 for arg in sys.argv[2:] if int(arg) > 0) 
with open(sys.argv[1]) as fp: 
    filteredlines = (line for n,line in enumerate(fp) if n not in omitlines) 
    sys.stdout.writelines(filteredlines) 

fileinput模块有一个inplace=True选项,标准输出重定向到该系统会自动为你改名后一个临时文件。

import fileinput 
exclude = set(map(int, sys.argv[2:])) 

for i, line in enumerate(fileinput.input('filename.txt', inplace=True), start=1): 
    if i not in exclude: 
     print line, # fileinput inplace=True redirects stdout to tempfile