簡體   English   中英

將選定的行從一個文件復制到另一個

[英]Copy selected lines from one file to another

我試圖用python編寫程序,該程序在txt文件中搜索用戶指定的單詞,並將包含該單詞的選定行復制到另一個文件中。

此外,用戶可以選擇排除任何單詞。

(例如,假設用戶搜索單詞“ exception”並想排除單詞“ abc”,那么代碼將僅復制其中包含“ exception”的行,而不是“ abc”的行)。

現在,所有工作將在命​​令提示符下完成。

輸入為:

file.py test.txt(input file) test_mod.txt(output file) -e abc(exclude word denoted by -e)-s exception(search word denoted by -s)

現在,用戶可以選擇輸入多個排除詞和多個搜索詞。

到目前為止,我已經實現了輸入格式為:

file.py test.txt test_mod.txt abc exception".

這排除了單詞“ abc”並搜索“ exception”。

但是我不知道如何:

  1. 包含多個搜索詞並排除詞
  2. 如何用-e和-s表示它們。 我看過argparse和getopt教程。 但是,沒有關於此特定主題的教程。

請有人可以通過修改我的代碼或編寫新代碼來幫助我嗎?

到目前為止,這是我的代碼:

#/Python33

import sys
import os




def main(): #main method

 try:

  f1 = open(sys.argv[1], 'r')    #takes the first input file in command line
  found = False
  user_input1 = (sys.argv[3])    #takes the word which is to be excluded.
  user_input2 = (sys.argv[4])    #takes the word which is to be included.
  if sys.argv[1] == sys.argv[2]: 
       f1.close()
       sys.exit('\nERROR!!\nThe two file names cannot be the same.') 

  if sys.argv[3] != sys.argv[4]:  

    for line in f1:

        if user_input1 in line or user_input2 in line:

           f2 = open(sys.argv[2], 'a') 

           if user_input1 in line:
              if user_input2 in line:
                   pass

           elif user_input2 in line:
              f2.write(line)
              found = True
              f2.close()


    if not found:
        print("ERROR: The Word couldn't be found.")            



    f1.close()


  if sys.argv[3] == sys.argv[4]: 
         f1.close()
         sys.exit('\nERROR!!\nThe word to be excluded and the word to be included  cannot be the same.') 



 except IOError:
       print('\nIO error or wrong file name.') 
 except IndexError:
       print('\nYou must enter 5 parameters.') #prevents less than 5 inputs which is  mandatory
 except SystemExit as e:                       #Exception handles sys.exit()
       sys.exit(e)


if __name__ == '__main__':
  main()

謝啦。 這確實幫助我理解了邏輯。 但是我是python的新手,所以我仍然遇到一些問題。每當我運行它時,它都會使用-s指定的單詞復制文件,但不排除-e指定的單詞。 我究竟做錯了什么? 所以這是我的代碼:#/ Python33

#takes a text file, finds a word and writes that line containing that word but not a 2nd word specified by the user. So if both of them are there, that line is not printed

import sys
import os
import argparse



def main(): #main method

 try:

  parser = argparse.ArgumentParser(description='Copies selected lines from files')
  parser.add_argument('input_file')
  parser.add_argument('output_file')
  parser.add_argument('-e',action="append")
  parser.add_argument('-s',action="append")
  args = parser.parse_args('test.txt, test_mod.txt, -e , -s exception'.split())


  user_input1 = (args.e)    #takes the word which is to be excluded.
  user_input2 = (args.s)    #takes the word which is to be included.

  def include_exclude(input_file, output_file, exclusion_list=[], inclusion_list=[]):


      with open(output_file, 'w') as fo:
        with open(input_file, 'r') as fi:
            for line in fi:
                inclusion_words_in_line = map(lambda x: x in line, inclusion_list)
                exclusion_words_in_line = map(lambda x: x in line, exclusion_list)
                if any(inclusion_words_in_line) and not any(exclusion_words_in_line):
                    fo.write(line)    
  if user_input1 != user_input2 : 
         include_exclude('test.txt', 'test_mod.txt', user_input1, user_input2);
         print("hello")

  if user_input1 == user_input2 : 


         sys.exit('\nERROR!!\nThe word to be excluded and the word to be included cannot be the same.') 



 except IOError:
       print('\nIO error or wrong file name.')  
 except IndexError:
       print('\nYou must enter 5 parameters.') 
 except SystemExit as e:                      
       sys.exit(e)


if __name__ == '__main__':
  main()

我認為這可以滿足您的需求:

»»» import argparse

»»» parser = argparse.ArgumentParser(description='foo baaar')

»»» parser.add_argument('input_file')
Out[3]: _StoreAction(option_strings=[], dest='input_file', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)

»»» parser.add_argument('output_file')
Out[4]: _StoreAction(option_strings=[], dest='output_file', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)

»»» parser.add_argument('-e', action="append")
Out[5]: _AppendAction(option_strings=['-e'], dest='e', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)

»»» parser.add_argument('-s', action="append")
Out[6]: _AppendAction(option_strings=['-s'], dest='s', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)

»»» parser.parse_args('foo1.txt foo2.txt -e abc -e def -s xyz -s pqr'.split())
Out[7]: Namespace(e=['abc', 'def'], input_file='foo1.txt', output_file='foo2.txt', s=['xyz', 'pqr'])

如果只調用parser.parse_args() ,它將解析傳遞給腳本的參數,但是上面的代碼很方便進行測試。 注意如何使用多個-s-e標志指定多個搜索和排除單詞。 通過將action="append"傳遞給add_argument方法,將-s-e之后的參數添加到parser.parse_args返回的名稱空間的列表中。 這應該解決您的問題1.2. .。

這是一個如何以一種很好的方式訪問值的示例:

»»» args = parser.parse_args('foo1.txt foo2.txt -e abc -e def -s xyz -s pqr'.split())

»»» args.e
Out[12]: ['abc', 'def']

我使用了argparse文檔 ,尤其是add_argument方法文檔非常有用。

編輯:這是一個執行包含/排除邏輯的功能:

def include_exclude(input_file, output_file, inclusion_list, exclusion_list=[]):
    with open(output_file, 'w') as fo:
        with open(input_file, 'r') as fi:
            for line in fi:
                inclusion_words_in_line = map(lambda x: x in line, inclusion_list)
                exclusion_words_in_line = map(lambda x: x in line, exclusion_list)
                if any(inclusion_words_in_line) and not any(exclusion_words_in_line):
                    fo.write(line)

with語句可確保在出現任何問題時正確關閉文件(請參閱doc )。 相反,您當然可以使用已經擁有的相同打開/關閉代碼。 確實,我的代碼不包含任何錯誤處理,我將其留給讀者練習。 在main for循環中,我遍歷輸入文件中的所有行。 然后,查看inclusion_list中的所有單詞,並檢查它們是否出現在該line map功能是恕我直言的一種優雅方式。 它需要(例如)詞語的inclusion_list ,和由每個項目的映射產生另一個列表inclusion_list給函數lambda x: x in line 如果輸入,該函數將返回True (該行中inclusion_list一個來自inclusion_list的單詞),因此最終得到的是True / False項目列表。 簡要示例:

»»» line="foo bar"

»»» words=['foo', 'barz']

»»» map(lambda x: x in line, words)
Out[24]: [True, False]

現在我應用any功能檢查,那么,任何在該項目的inclusion_words_in_line名單是真實的,並檢查無( not any在exclusion_words_in_line的項目),都是如此。 在這種情況下,該line附加到輸出文件。 如果你想確保all的話inclusion_list出現在該行,而不是任何(這不是從你的問題描述清楚地知道),你可以使用all功能來代替。

請注意,您可以使用for循環輕松地解決上述問題,這些循環遍歷inclusion_listexclusion_list ,檢查是否有項目,不需要使用mapany

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM