2012-06-25 100 views
0

我有以下python脚本,它需要一些输入,并根据sys.argv将它们放在文件中。我想添加一些重复的条目检查...如果一个值通过sys.argv传递到一个文件中,但它已经存在,则不执行任何操作,否则将文本行打印到文件中。Python grep,如果语句

我正在考虑使用子进程和使用系统find/grep命令(分别用于windows/linux),但是我无法让这个测试工作。

任何想法/代码欢迎。

感谢

# Import Modules for script 
import os, sys, fileinput, platform, subprocess 

# Global variables 
hostsFile = "hosts.txt" 
hostsLookFile = "hosts.csv" 
hostsURLFileLoc = "urls.conf" 

# Determine platform 
plat = platform.system() 

if plat == "Windows": 

# Define Variables based on Windows and process 
    #currentDir = os.getcwd() 
    currentDir = "C:\\Program Files\\Splunk\\etc\\apps\\foo\\bin" 
    hostsFileLoc = currentDir + "\\" + hostsFile 
    hostsLookFileLoc = currentDir + "\\..\\lookups\\" + hostsLookFile 
    hostsURLFileLoc = currentDir + "\\..\\default\\" + hostsURLFileLoc 
    hostIP = sys.argv[1] 
    hostName = sys.argv[2] 
    hostURL = sys.argv[3] 
    hostMan = sys.argv[4] 
    hostModel = sys.argv[5] 
     hostDC = sys.argv[6] 



    # Add ipAddress to the hosts file for python to process 
    with open(hostsFileLoc,'a') as hostsFilePython: 

#  print "Adding ipAddress: " + hostIP + " to file for ping testing" 
#  print "Adding details: " + hostIP + "," + hostName + "," + hostURL + "," + hostMan + "," + hostModel + " to file" 
     hostsFilePython.write(hostIP + "\n") 

    # Add all details to the lookup file for displaying on-screen and added value 
    with open(hostsLookFileLoc,'a') as hostsLookFileCSV: 

     hostsLookFileCSV.write(hostIP + "," + hostName + "," + hostURL + "," + hostMan + "," + hostModel + "," + hostDC +"\n") 

    if hostURL != "*": 

     with open(hostsURLFileLoc,'a+') as hostsURLPython: 

      hostsURLPython.write("[" + hostName + "]\n" + "ping_url = " + hostURL + "\n") 

UPDATE:我想叫基础上,通过提供steveha,我在与os.rename部分麻烦小片段

>>> import os 
>>> import sys 
>>> in_file = "inFile.txt" 
>>> out_file = "outFile.txt" 
>>> dir = "C:\\Python27\\" 
>>> found_in_file = False 
>>> with open(in_file) as in_f, open(out_file,"w") as out_f: 
...  for line in in_f: 
...    if line.endswith("dax"): 
...      found_in_file = True 
...  if not found_in_file: 
...    out_f.write("192.168.0.199\tdax\n") 
...  os.rename(os.path.join(dir, in_f), os.path.join(dir,out_f)) 

到我得到以下错误。

Traceback (most recent call last): 
    File "<stdin>", line 7, in <module> 
    File "C:\Python27\lib\ntpath.py", line 73, in join 
    elif isabs(b): 
    File "C:\Python27\lib\ntpath.py", line 57, in isabs 
    s = splitdrive(s)[1] 
    File "C:\Python27\lib\ntpath.py", line 125, in splitdrive 
    if p[1:2] == ':': 
TypeError: 'file' object is not subscriptable 

有什么想法?

+1

[建议不要在同一行放置多个导入。](http://www.python.org/dev/peps/pep-0008/#imports) – moooeeeep

+0

是否有这个原因...我是python新手,我只是假定它比较整洁。 – MHibbin

+1

@moooeeeep将他的整个评论变成可点击的链接。如果你点击它,你会被带到一个网页,该网页解释了这个原因。 – steveha

回答

1

它会更容易,更快,直接做的“grep”任务的Python:

with open("filename") as f: 
    for line in f: 
     if "foo" in line: 
      ... # do something to handle the case of "foo" in line 

这里是一个程序,将一个名为“DAX”主机添加到/etc/hosts

import sys 
_, in_fname, out_fname = sys.argv 

found_in_file = False 
with open(in_fname) as in_f, open(out_fname, "w") as out_f: 
    for line in lst: 
     if line.endswith("dax"): 
      found_in_file = True 
     out_f.write(line) 
    if not found_in_file: 
     out_f.write("192.168.0.199\tdax\n") 

指定两个文件名,输出文件名将得到/etc/hosts的副本。如果系统名称“dax”已在/etc/hosts中找到,则该副本将是确切的;否则会附加一行。

您可以通过使用正则表达式来检测特定行来扩展此想法,并且可以通过编写不同的行而非原始行来编辑行。

该程序使用正则表达式查找/etc/hosts文件中的所有条目,范围从192.168.0.10192.168.0.59(含)。这些行被重写,将它们移动到192.168.1.*,其中*是原始地址,保持不变。

import re 
import sys 
_, in_fname, out_fname = sys.argv 

pat = re.compile(r'^192.168.0.(\d+)\s+(\S+)') 

with open(in_fname) as in_f, open(out_fname, "w") as out_f: 
    for line in in_f: 
     m = pat.search(line) 
     if m: 
      x = int(m.group(1)) 
      if 10 <= x < 60: 
       line = "192.168.1." + str(x) + "\t" + m.group(2) + "\n" 
     out_f.write(line) 

当你已经成功写入输出文件,并没有错误,你可以使用os.rename()到新的文件重命名为原来的文件名,从而覆盖旧的文件。如果您发现您不需要更改旧文件中的任何行,则可以删除新文件而不是重命名它;如果您总是重命名,即使您没有真正更改任何内容,也会更新文件上的修改时间戳。

编辑:这里是运行最后一个代码示例的示例。假设你把代码放到一个名为move_subnet.py文件,然后在Linux或其他* NIX,你可以像这样运行:

python move_subnet.py /etc/hosts ./hosts_copy.txt 

如果您使用的是Windows,它会是这样的:

python move_subnet.py C:/Windows/system32/drivers/etc/hosts ./hosts_copy.txt 

请注意,Windows可以在文件名中使用反斜杠或正斜杠。在这个例子中我使用了正斜杠。

您的输出文件将在当前目录中为hosts_copy.txt

+0

嗨steveha, 感谢您的快速响应, 我有点困惑这是如何工作的。我已经尝试将代码写入文件并对其进行测试,但是我只是发现文件不存在的错误:-S – MHibbin

+0

@MHibbin您是否尝试过将代码片段调整为适合您的情况? – moooeeeep

+0

@moooeeeep&@steveha, 我已经更新了我想要在上面的答案中工作的一段代码。我在os.rename部分遇到问题。 'import os' 'import sys' 'in_file =“inFile.txt”' – MHibbin