How to convert a txt to csv in perl?

Asked

Viewed 65 times

3

Hello, Little Boy.

I am new to perl. I need to convert a txt file to csv.

Follow the code I’ve managed so far.

#!/usr/bin/perl

my $filename = "interfaces.txt";

open(fh, $filename) or die "não abriu";
@fh = <fh>;
close fh;

print "Interfaces;Status;Protocol;Description\n";

foreach my $linha (@fh){
        if($linha =~ /[gi]+\d\W\d+|[te]+\d\W\d+/gi){
                my @te = $linha;

                foreach my $linha2 (@te){
                        $linha2 =~ s/\s\ //g;
                        print "$linha2";
                }
        }
}

This is the content of the txt:

Interface                      Status         Protocol Description
Gi1/1                          up             up       descrição...
Gi1/2                          up             down     descrição...
Gi1/3                          up             up       descrição...
Gi1/48                         admin down     down     descrição...
Te1/49                         up             up       descrição...
Te1/50                         up             up       descrição...

So he should stay:

Interface;Status;Protocol;Description
Gi1/1;up;up;descrição...
Gi1/2;up;down;descrição...
Gi1/3;up;up;descrição...
Gi1/48;admin down;down;descrição...
Te1/49;up;up;descrição...
Te1/50;up;up;descrição...

And that’s what I got so far:

Interface;Status;Protocol;Description
Gi1/1up up descrição...
Gi1/2up down descrição...
Gi1/3up up descrição...
Gi1/48 admin down down descrição...
Te1/49 up up descrição...
Te1/50 up up descrição...

Anyone who can help, I’d be grateful.

  • Take a look at the call split. Nor would I recommend having the headers fixed inside your program - the treatment for the header line may be the same as for the entire text file, and your program is generic. this way it will work only for this specific file.

  • About the concepts involved -keep in mind that a "csv file" also is a text file, but structured according to some conventions. The extension in the case is just a reminder to the user. In case, your file ". txt" can be understood directly as a CSV by various applications, simply indicating that the separator is blank spaces, and not the ";".

  • @jsbueno, in the case of the header, it will Generico even, only the content q will change. I need to convert to csv to decrease the whitespace and put " ; "to separate, as I have tried with whitespace, but it interprets "admin down" with 3 values, in this case are 2 "admin down;down". I’m seeing how this fuciona the split function I’ve had a good progress.

  • hmm.. this admin down down can be a problem - can see if they are spaces or tabs (code 9 character) separating the columns?

  • In case, are mirrors q are separating the columns. I tried to convert to t but failed.

  • 1

    @jsbueno, I was able to complete the scritp. Thank you very much for your help. I will paste the resolution as a response.

  • Hello @Natanael, Do not change the question title to indicate that your problem has been solved. If you have found a different response from the proposals by the community consider answering your own question, but later you may accept it, it may help people with the same problem =D -- I can answer my own question? -- If any community response helped you consider accepting, this would be the best way to thank. = D -- [Tour]

  • 1

    Ah, yes. Thank you so much for your attention @Icaromartins

Show 3 more comments

2 answers

3


By the way a little more Trotskyist alternative:

#!/usr/bin/perl
use strict;
while(<>){                                ## para cada linha
  s/(\s{2,}|\t| (?=[A-Z]))/;/g;           ## substuir espaços por ;
  print                                   ## imprimi-la
}

Where you’re just filling in (s/(\s{2,}|\t| (?=[A-Z]))/;/g)

  • 2 or more spaces, or
  • a tab or
  • a single space if followed by a capital letter

by the separator ;

You can also do it directly on the command line:

perl -pE 's/(\s{2,}|\t| (?=[A-Z]))/;/g' input > output.csv
  • Your solution is much simpler compared to mine. Thanks for sharing, it worked perfectly!

3

The problem has been solved!!

Follows solution script:

#!/usr/bin/perl

my $filename = "interfaces.txt";
my $interface;
my $status;
my $protocol;
my $description;

open(fh, $filename) or die "não abriu";
@fh = <fh>;
close fh;

print "Interfaces;Status;Protocol;Description\n";

foreach my $linha (@fh){
        if($linha =~ /[gi]+\d\W\d+|[te]+\d\W\d+/gi){
                $linha =~ s/\s  //g;
                my @te = split / /, $linha;
                $interface = $te[0];

                $linha =~ s/Gi+\d\W\d+\s+|Te+\d\W\d+\s+//g;
                my @tt = split / /, $linha;

                if($tt[0] =~ /up|down/gi){
                        $status = $tt[0];
                         if($tt[1] =~ /up|down/g){
                                $protocol = $tt[1];
                        } else{
                                $protocol = $tt[2];
                        }
                } elsif($tt[0] =~ /admin/gi) {
                        $status = "$tt[0] $tt[1]";
                        $protocol = $tt[3];
                }

                $linha =~ s/\s  |Gi+\d\W\d+|Te+\d\W\d+|up|admin|down//g;
                $linha =~ s/^\s+//gm;
                $description = $linha;

                print "$interface;$status;$protocol;$description";
        }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.