我最近收到了大量要分析的电子邮件。副本被转换为txt和html文件并提取到相同的子目录中。然后,数据按字段代码排序,并使用各种cmd /批处理脚本输入到电子表格中。之后,有必要确定造成问题的每个附件的文件名。
findstr能够使用以下命令成功识别每个附件的路径,电子邮件和文件名,并将其保存到输出日志中:
findstr /s Attachments: *.* >>Find_Attachments_Files2.txt
不幸的是,findstr只会在“附件:”之后找到第一个文件名,仅此而已。 我需要找到并记录,“附件:”和第二个标记之间的路径,文件和每个文本块,在这种情况下,是一系列破折号(“----” ),除此之外没什么。
短信类似于下面显示的格式,不限于任何固定值/行#:
Attachments: Purely Practical.pdf
Daily Revenue.xls
Advertising_Ideas.doc
来自:“Mouse,Mickey”Mickey.Mouse@mouseclick.com
在marker1和marker2之间捕获文本块的能力非常重要,并且解决这个特定问题是一个更广泛的问题,应该相应地构建。尽管搜索和替换功能具有重要价值,但搜索和报告功能可能是最重要的。
是什么让这如此不完美和困难?有什么建议或可靠的解决方案吗?
答案 0 :(得分:1)
我不确定这是否有效,这只是一个理论,但我认为值得一试。
我认为在执行完成后,findstr命令可能会发出错误级别。如果errorlevel在找到字符串时不同。如果没有找到字符串,则会出现不同的错误级别。
如果这确实有效,那么你可以做类似于while循环的事情,例如
:A
findstr :: And then the full command
if errorlevel == 1 goto A :: If the string has been found
goto B :: The rest of your code
这只是理论上的
要保存输出,您应该可以执行类似这样的命令>> log.txt ::这会将命令的输出保存到名为log的文本文件中。
答案 1 :(得分:0)
我对此的看法,从高到低......
为什么这不完美和困难?因为尽管你已经足够努力改进这个问题,但它仍然有很多不确定的问题,但它已经相当复杂了。幸运的是,其他人也同样探索了文本文件,并开发了整个编程语言来处理它。但即使你已经彻底了解了其中的一些,你仍然会被咬伤,因为按照你的规范行事的计算机是令人费解的愚蠢。快,但很愚蠢。
使用开箱即用的东西,比如findstr,egrep ......来处理这个特殊的问题对我来说几乎是不可能的。像Python这样的编程语言是一种更可行和面向未来的匹配。
那么编程任务有两个部分:
对于后者,正则表达式确实看起来像一个可行的机制,但第一个问题是,你能负担得起吗?显然,我们需要多行处理,每当我看到它完成时,它就会立即存在于整个文件中。你能负担得起将整个文件读入内存吗?你能负担得起从磁盘上读取整个文件 - 也许标题位于文件的顶部并且读取整个文件是浪费的吗?我假设没有问题。
使用单个正则表达式直接从文件中提取单个附件名称似乎非常复杂(甚至in a language that supports repeating captures)。所以我会让正则表达式首先找到列表,然后将其拆分。甚至没有考虑你的.txt文件是什么意思,并且有太少的测试用例被隐藏起来,这让我们:
import os
import re
searcher = re.compile(r"^Attachments: (.+?)^---+$", flags=re.MULTILINE+re.DOTALL)
def visitFile(filepath, out):
with open(filepath) as f:
match = searcher.search(f.read())
if match:
for name in match.group(1).split('\n')[:-1]:
out.write("%s\t%s\n" % (filepath, name))
def visitFolder(topdirpath, out):
for dirpath, subdirnames, filenames in os.walk(topdirpath):
subdirnames.sort() # if needed
filenames.sort() # if needed
for filename in filenames:
visitFile(os.path.join(dirpath, filename), out)
if __name__ == "main":
visitFolder(sys.argv[1], sys.out)
import io
import tempfile
import unittest
class FolderBasedTestCase(unittest.TestCase):
def setUp(self):
self.tempdir = tempfile.TemporaryDirectory(prefix="test_dir_")
self.out = io.StringIO()
def tearDown(self):
self.tempdir.cleanup()
self.out.close()
def walkthewalk(self):
visitFolder(self.tempdir.name, self.out)
class EmptyFolderTestCase(FolderBasedTestCase):
def runTest(self):
self.walkthewalk()
self.assertEqual(self.out.getvalue(), "")
class FriendTestCase(FolderBasedTestCase):
def setUp(self):
super().setUp()
with open(os.path.join(self.tempdir.name, "friend"), "w") as f:
f.write("Some: Stuff\n" +
"Attachments: Purely Practical.pdf\n" +
"Daily Revenue.xls\n" +
"Advertising_Ideas.doc\n" +
"-------------\n" +
'From: "Mouse, Mickey" Mickey.Mouse@mouseclick.com\n')
def runTest(self):
self.walkthewalk()
self.assertEqual(self.out.getvalue().replace(self.tempdir.name + os.sep, "{p}"),
"{p}friend\tPurely Practical.pdf\n" +
"{p}friend\tDaily Revenue.xls\n" +
"{p}friend\tAdvertising_Ideas.doc\n")
class FooTestCase(FolderBasedTestCase):
def setUp(self):
super().setUp()
with open(os.path.join(self.tempdir.name, "foo"), "w") as f:
f.write("From: your worst enemy\n" +
"\n" +
"Mail body here. This week's topics:\n" +
"Attachments: are't they a pain?\n" +
"Pain: don't we get attached to it?\n" +
"\n")
def runTest(self):
self.walkthewalk()
self.assertEqual(self.out.getvalue(), "")
请注意正则表达式(希望)与文件的换行风格无关,但是,就目前而言,split()
需要右行分隔符。
我怀疑单独编译和存储正则表达式有任何人都会注意到的性能优势,但我认为对于这么少的代码,它实际上使事情更具可读性。
要运行单元测试,特别是如果将代码和测试用例存储在单个文件scriptname.py中,请执行`python -m unittest scriptname'。