用于在单词A和单词B之间查找文本字符串的脚本findtr,Regex或替代

时间:2015-08-22 05:21:50

标签: regex batch-file cmd

我最近收到了大量要分析的电子邮件。副本被转换为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之间捕获文本块的能力非常重要,并且解决这个特定问题是一个更广泛的问题,应该相应地构建。尽管搜索和替换功能具有重要价值,但搜索和报告功能可能是最重要的。

是什么让这如此不完美和困难?有什么建议或可靠的解决方案吗?

2 个答案:

答案 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这样的编程语言是一种更可行和面向未来的匹配。

那么编程任务有两个部分:

  1. 走一个目录树来访问每个文件
  2. 查找每个文件的内容
  3. 对于后者,正则表达式确实看起来像一个可行的机制,但第一个问题是,你能负担得起吗?显然,我们需要多行处理,每当我看到它完成时,它就会立即存在于整个文件中。你能负担得起将整个文件读入内存吗?你能负担得起从磁盘上读取整个文件 - 也许标题位于文件的顶部并且读取整个文件是浪费的吗?我假设没有问题。

    使用单个正则表达式直接从文件中提取单个附件名称似乎非常复杂(甚至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'。