在Python中合并多行(文本格式)

0 投票
3 回答
3471 浏览
提问于 2025-04-17 19:45

我正在通过一个网络接口获取日志,目前获取到的日志格式如下(下面有3个事件,都是以某个字符开头,以句点结束)。我的问题是,怎样才能逐行处理这些日志,并把它们连接起来,最终得到我想要的结果。

现在的输出

<attack_headlines version="1.0.1">
  <attack_headline>
    <site_id>1</site_id>
    <category>V2luZG93cyBEaXJlY3RvcmllcyBhbmQgRmlsZXM=</category>
    <subcategory>SUlTIEhlbHA=</subcategory>
    <client_ip>172.17.1.126</client_ip>
    <date>1363735940</date>
    <gmt_diff>0</gmt_diff>
    <reference_id>6D13-DE3D-9539-8980</reference_id>
  </attack_headline>
</attack_headlines>
<attack_headlines version="1.0.1">
  <attack_headline>
    <site_id>1</site_id>
    <category>V2luZG93cyBEaXJlY3RvcmllcyBhbmQgRmlsZXM=</category>
    <subcategory>SUlTIEhlbHA=</subcategory>
    <client_ip>172.17.1.136</client_ip>
    <date>1363735971</date>
    <gmt_diff>0</gmt_diff>
    <reference_id>6D13-DE3D-9539-8981</reference_id>
  </attack_headline>
</attack_headlines>
<attack_headlines version="1.0.1">
  <attack_headline>
    <site_id>1</site_id>
    <category>V2luZG93cyBEaXJlY3RvcmllcyBhbmQgRmlsZXM=</category>
    <subcategory>SUlTIEhlbHA=</subcategory>
    <client_ip>172.17.1.156</client_ip>
    <date>1363735975</date>
    <gmt_diff>0</gmt_diff>
    <reference_id>6D13-DE3D-9539-8982</reference_id>
  </attack_headline>
</attack_headlines>

期望的输出

<attack_headlines version="1.0.1"><attack_headline><site_id>1</site_id<category>V2luZG93cyBEaXJlY3RvcmllcyBhbmQgRmlsZXM=</category<subcategory>SUlTIEhlbHA=</subcategory><client_ip>172.17.1.156</client_ip<date>1363735975</date><gmt_diff>0</gmt_diff<reference_id>6D13-DE3D-9539-8982</reference_id></attack_headline</attack_headlines>

提前谢谢你们!

import json
import os
from suds.transport.https import WindowsHttpAuthenticated

class Helpers:
        def set_connection(self,conf):
                        #SUDS BUG FIXER(doctor)
                        protocol=conf['protocol']
                        hostname=conf['hostname']
                        port=conf['port']
                        path=conf['path']
                        file=conf['file']
                        u_name=conf['login']
                        passwrd=conf['password']
                        auth_type = conf['authType']

                        from suds.xsd.doctor import ImportDoctor, Import
                        from suds.client import Client

                        url = '{0}://{1}:{2}/{3}/{4}?wsdl'.format(protocol,
                        hostname,port, path, file)

                        imp = Import('http://schemas.xmlsoap.org/soap/encoding/')
                        d = ImportDoctor(imp)
                        if(auth_type == 'ntlm'):
                                ntlm = WindowsHttpAuthenticated(username=u_name, password=passwrd)
                                client = Client(url, transport=ntlm, doctor=d)
                        else:
                                client = Client(url, username=u_name, password=passwrd, doctor=d)
                        return client
        def read_from_file(self, filename):
                try:
                        fo = open(filename, "r")
                        try:
                                result = fo.read()
                        finally:
                                fo.close()
                                return result
                except IOError:
                        print "##Error opening/reading file {0}".format(filename)
                        exit(-1)


        def read_json(self,filename):
                string=self.read_from_file(filename)
                return json.loads(string)


        def get_recent_attacks(self, client):
            import time
            import base64
            from xml.dom.minidom import parseString
            epoch_time_now = int(time.time())
            epochtimeread = open('epoch_last', 'r')
            epoch_time_last_read = epochtimeread.read()
            epochtimeread.close()
            epoch_time_last = int(float(epoch_time_last_read))
            print client.service.get_recent_attacks("",epoch_time_last,epoch_time_now,1,"",15)

3 个回答

0

在编程中,很多时候我们需要处理一些数据,这些数据可能来自不同的地方,比如用户输入、文件或者网络请求。为了让程序能够理解这些数据,我们通常需要将它们转换成程序能处理的格式。

比如说,如果你从一个网页上获取了一些信息,这些信息可能是以文本的形式存在的。为了让程序能够使用这些信息,我们可能需要把它们转化为数字、日期或者其他类型的数据。这个过程叫做“数据解析”。

在解析数据时,我们可能会用到一些工具或库,这些工具可以帮助我们更轻松地处理数据。比如,有些库可以自动识别数据的格式,并将其转换为我们需要的类型,这样我们就不用手动去处理每一条数据了。

总之,数据解析是一个非常重要的步骤,它帮助我们把原始数据变成可以被程序理解和使用的格式。

import re
# remove all newline whitespace stuff as in answer given before:
text = re.sub(r'\s*\n\s*', '', text)
# break again at desired points:
text = re.sub(r'</attack_headlines>', '</attack_headlines>\n', text)
1

你可以这样做:

oneline = "".join(multiline.split())

编辑 1(我刚看到你的修改) - 我会把你的代码改成这样:

with open(filename, "r") as fo:
    result = []
    for line in fo.readlines():
        result.append(line.strip())
    return result

编辑 2(我看了你在另一个回答上的评论) - 你可以这样做:

with open(filename, "r") as fo:
    partial = []
    for line in fo.readlines():
        if line.startswith("<"):
            yield "".join(partial)
            partial = []
        else:
            clean = line.strip()
            if clean:
                partial.append(clean)
1

如果这只是一个很大的字符串对象,并且里面有换行符,你可以直接把它们删掉:

import re
text = re.sub('\s*\n\s*', '', text)

如果你想保留在</attack_headline>这个分隔符后面的换行符,可以试试:

re.sub('(?<!<\/attack_headline>)\s*\n\s*', '',  x)

撰写回答