Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #56708

Re: Consolidate several lines of a CSV file with firewall rules

Path csiph.com!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!newsfeed.xs4all.nl!newsfeed1.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail
Return-Path <python.list@tim.thechases.com>
X-Original-To python-list@python.org
Delivered-To python-list@mail.python.org
X-Spam-Status OK 0.000
X-Spam-Evidence '*H*': 1.00; '*S*': 0.00; 'else:': 0.03; 'read.': 0.03; 'output': 0.05; 'subsequent': 0.05; 'column': 0.07; 'subject:file': 0.07; 'append': 0.09; 'filenames': 0.09; 'module)': 0.09; 'parsers': 0.09; 'skip:1 70': 0.09; '"r")': 0.16; '-tkc': 0.16; 'columns': 0.16; 'concatenate': 0.16; 'csv': 0.16; 'from:addr:python.list': 0.16; 'from:addr:tim.thechases.com': 0.16; 'from:name:tim chase': 0.16; 'row)': 0.16; 'subject:CSV': 0.16; 'subject:several': 0.16; 'weird': 0.16; 'wrote:': 0.18; "python's": 0.19; 'not,': 0.20; 'code,': 0.22; 'import': 0.22; 'source': 0.25; 'first,': 0.26; 'this:': 0.26; 'gets': 0.27; 'header:In-Reply-To:1': 0.27; 'said,': 0.30; 'code': 0.31; 'lines': 0.31; 'text': 0.33; 'there,': 0.34; 'subject:with': 0.35; 'something': 0.35; 'good.': 0.35; 'there': 0.35; 'adjust': 0.36; 'data,': 0.36; 'next': 0.36; 'charset:us-ascii': 0.36; "i'll": 0.36; 'should': 0.36; 'skip:o 20': 0.38; 'to:addr:python-list': 0.38; 'previous': 0.38; 'to:addr:python.org': 0.39; 'read': 0.60; 'skip:n 30': 0.60; 'most': 0.60; 'hope': 0.61; 'new': 0.61; 'first': 0.61; 'more': 0.64; 'number:': 0.66; 'evaluate': 0.72; 'received:50.22': 0.84; 'want:': 0.84; 'behaviors.': 0.91
Date Fri, 11 Oct 2013 15:40:46 -0500
From Tim Chase <python.list@tim.thechases.com>
To python-list@python.org
Subject Re: Consolidate several lines of a CSV file with firewall rules
In-Reply-To <9190d949-7b03-4579-8d46-c42afcc9d0fa@googlegroups.com>
References <9190d949-7b03-4579-8d46-c42afcc9d0fa@googlegroups.com>
X-Mailer Claws Mail 3.8.1 (GTK+ 2.24.10; x86_64-pc-linux-gnu)
Mime-Version 1.0
Content-Type text/plain; charset=US-ASCII
Content-Transfer-Encoding 7bit
X-AntiAbuse This header was added to track abuse, please include it with any abuse report
X-AntiAbuse Primary Hostname - boston.accountservergroup.com
X-AntiAbuse Original Domain - python.org
X-AntiAbuse Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse Sender Address Domain - tim.thechases.com
X-Get-Message-Sender-Via boston.accountservergroup.com: none
X-BeenThere python-list@python.org
X-Mailman-Version 2.1.15
Precedence list
List-Id General discussion list for the Python programming language <python-list.python.org>
List-Unsubscribe <https://mail.python.org/mailman/options/python-list>, <mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive <http://mail.python.org/pipermail/python-list/>
List-Post <mailto:python-list@python.org>
List-Help <mailto:python-list-request@python.org?subject=help>
List-Subscribe <https://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe>
Newsgroups comp.lang.python
Message-ID <mailman.1016.1381523955.18130.python-list@python.org> (permalink)
Lines 88
NNTP-Posting-Host 2001:888:2000:d::a6
X-Trace 1381523955 news.xs4all.nl 15916 [2001:888:2000:d::a6]:54779
X-Complaints-To abuse@xs4all.nl
Xref csiph.com comp.lang.python:56708

Show key headers only | View raw


On 2013-10-11 08:01, Starriol wrote:
> NO.;NAME;SOURCE;DESTINATION;VPN&nbsp;&nbsp;;SERVICE;ACTION;TRACK;INSTALL
> ON;TIME;COMMENT
> 1;;fwxcluster;mcast_vrrp;;vrrp;accept;Log;fwxcluster;Any;"VRRP;;*Comment
> suppressed* ;;;;;igmp**;;;;;
> 2;;fwxcluster;fwxcluster;;FireWall;accept;Log;fwxcluster;Any;"Management
> FWg;*Comment
> suppressed* ;;fwmgmpe**;fwmgmpe**;;ssh**;;;;; ;;fwmgm**;fwmgm**;;;;;;;
> 3;NTP;G_NTP_Clients;cmm_ntpserver_pe01;;ntp;accept;None;fwxcluster;Any;*Comment
> suppressed* ;;;cmm_ntpserver_pe02**;;;;;;; 
> What I need ,explained in pseudo code, is this:
> 
> Read the first column of the next line. If there's a number:
> 	Evaluate the first column of the next line. If there's no
> number there, concatenate (separating with a comma) \ the strings
> in the columns of this line with the last one and eliminate the
> text in the current one
> 
> The output should be something like this:
> 
> NO.;NAME;SOURCE;DESTINATION;VPN&nbsp;&nbsp;;SERVICE;ACTION;TRACK;INSTALL
> ON;TIME;COMMENT
> 1;;fwxcluster,fwmgmpe**,fwmgm**;mcast_vrrp,fwmgmpe**,fwmgm**;;vrrp,ssh**;accept;Log;fwxcluster;Any;*Comment
> suppressed* ;;;;;;;;;; ;;;;;;;;;;
> 3;NTP;G_NTP_Clients;cmm_ntpserver_pe01,cmm_ntpserver_pe02**;;ntp;accept;None;fwxcluster;Any;*Comment
> suppressed* ;;;;;;;;;;
>
> The empty lines are there only to be more clear, I don't actually
> need them.

Though there are a couple oddities in your source data, I'll take a
crack at it.  First, there are the dangling open-quotes on #1 that
cause most CSV parsers (I tested both Gnumeric and Python's csv
module) to read until the subsequent line is read.  If this is
intentional, then it's all good.  If not, you get weird behaviors.
That said, you can try the code below (adjusting the 3 lines for
your desired filenames and whether you *want* to write emptied rows)
to see if it gets you what you want:

##########################################################

import csv
# adjust these 3 lines
WRITE_EMPTIES = True
INFILE = "input.txt"
OUTFILE = "output.txt"
with open(INFILE, "r") as in_file:
  r = csv.reader(in_file, delimiter=";")
  with open(OUTFILE, "wb") as out_file:
    previous = None
    empties_to_write = 0
    out_writer = csv.writer(out_file, delimiter=";")
    for i, row in enumerate(r):
      first_val = row[0].strip()
      if first_val:
        if previous:
          out_writer.writerow(previous)
          if WRITE_EMPTIES and empties_to_write:
            out_writer.writerows(
              [["" for _ in previous]] * empties_to_write
              )
            empties_to_write = 0
        previous = row
      else: # append sub-portions to each other
        previous = [
          ",".join(
            subitem
            for subitem in existing.split(",") + [new]
            if subitem
            )
          for existing, new in zip(previous, row)
          ]
        empties_to_write += 1
    if previous: # take care of the last row
      out_writer.writerow(previous)
      if WRITE_EMPTIES and empties_to_write:
        out_writer.writerows(
          [["" for _ in previous]] * empties_to_write
          )
####################################################

Hope this helps,

-tkc



Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Consolidate several lines of a CSV file with firewall rules Starriol <juanscopp@gmail.com> - 2013-10-11 08:01 -0700
  Re: Consolidate several lines of a CSV file with firewall rules Joel Goldstick <joel.goldstick@gmail.com> - 2013-10-11 11:47 -0400
  Re: Consolidate several lines of a CSV file with firewall rules Tim Chase <python.list@tim.thechases.com> - 2013-10-11 15:40 -0500
  Re: Consolidate several lines of a CSV file with firewall rules [PS] Tim Chase <python.list@tim.thechases.com> - 2013-10-11 15:50 -0500
    Re: Consolidate several lines of a CSV file with firewall rules [PS] Starriol <juanscopp@gmail.com> - 2013-10-11 14:22 -0700
      Re: Consolidate several lines of a CSV file with firewall rules [PS] Mark Lawrence <breamoreboy@yahoo.co.uk> - 2013-10-11 23:40 +0100

csiph-web