[英]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”。
但是我不知道如何:
请有人可以通过修改我的代码或编写新代码来帮助我吗?
到目前为止,这是我的代码:
#/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_list
和exclusion_list
,检查是否有项目,不需要使用map
和any
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.