tags:

views:

100

answers:

4

hello , I need help about how to numeration text in file.

I have also linux machine and I need to write the script with perl

I have file name: file_db.txt

In this file have parameters like name,ParameterFromBook,NumberPage,BOOK_From_library,price etc Each parameter equal to something as name=elephant

My question How to do this by perl

I want to give number for each parameter (before the "=") that repeated (unique parameter) in the file , and increase by (+1) the new number of the next repeated parameter until EOF

lidia

For example

file_db.txt before numbering

    parameter=1
    name=one

    parameter=2
    name=two

file_db.txt after parameters numbering

    parameter1=1
    name1=one

    parameter2=2
    name2=two
  • other examples

Example1 before

    name=elephant
    ParameterFromBook=234
    name=star.world
    ParameterFromBook=200
    name=home_room1
    ParameterFromBook=264

Example1 after parameters numbering

    name1=elephant
    ParameterFromBook1=234
    name2=star.world
    ParameterFromBook2=200
    name3=home_room1
    ParameterFromBook3=264

Example2 before

file_db.txt before numbering

       lines_and_words=1
       list_of_books=3442

       lines_and_words=13
       list_of_books=344224

       lines_and_words=120
       list_of_books=341

Example2 after

file_db.txt after parameters numbering

        lines_and_words1=1
        list_of_books1=3442

        lines_and_words2=13
        list_of_books2=344224

        lines_and_words3=120
        list_of_books3=341
A: 

in pretty much pseudo code:

open(DATA, "file");
my @lines = <DATA>;
my %tags;
foreach line (@lines)
{
    my %parts=split(/=/, $line);
    my $name=$parts[0];
    my $value=$parts[1];

    $name = ${name}$tags{ $name };
    $tags{ $name } = $tags{ $name } + 1;
    printf "${name}=$value\n";
}
close( DATA );

This looks like a CS101 assignment. Is it really good to ask for complete solutions instead of asking specific technical questions if you have difficulty?

n-alexander
I get error like: Missing $ on loop variable at ./stam line 8.???
lidia
@lidia As n-alexander said, it's pseudo-code (sort of). The idea is that _you_ now turn it into a final solution. We're not here to write code for you.
Telemachus
I begin to lern perlso if you can please help me?
lidia
@lidia The best way to learn is to read and try. Post back if you have _specific_ problems. Otherwise, it looks like you're not trying to learn, you're trying to get code. Here's a good (and free) introductory book http://www.perl.org/books/beginning-perl/
Telemachus
Also, don't use examples like this for learning Perl, go read beginning perl like @Telemachus said. That 'open DATA, "file"' notation is not only *old* but *dangerous* to use in the real world.
Kent Fredric
A: 

If Perl is not a must, here's an awk version

$ cat  file
    name=elephant
    ParameterFromBook=234
    name=star.world
    ParameterFromBook=200
    name=home_room1
    ParameterFromBook=264

$ awk -F"=" '{s[$1]++}{print $1s[$1],$2}' OFS="=" file
    name1=elephant
    ParameterFromBook1=234
    name2=star.world
    ParameterFromBook2=200
    name3=home_room1
    ParameterFromBook3=264
ghostdog74
how to build the awk in the perl script?
lidia
I mentioned that if you are not restricted to Perl, you can use this awk one liner. Otherwise, look at the other Perl answers for inspiration
ghostdog74
is it possible to integrated it with system?
lidia
you mean Perl's system() ? yes of course, but don't do that please. There are many Perl answers here. Go and have them tested out.
ghostdog74
hiI run the system(" awk -F"=" '{s[$1]++}{print $1s[$1],$2}' OFS="=" file " ); but I get errors? like Can't modify string in scalar assignment at
lidia
you'll have to learn a bit more Perl before you can put such a command into a system() call. It's not easy
n-alexander
+1  A: 

The way I look at it, you probably want to number blocks and not just occurrences. So you probably want the number on each of the keys to be at least as great as the earliest repeating key.

my $in  = \*::DATA;  
my $out = \*::STDOUT;
my %occur;
my $num = 0;
while ( <$in> ) {
    if ( my ( $pre, $key, $data ) = m/^(\s*)(\w+)=(.*)/ ) { 
        $num++ if $num < ++$occur{$key};
        print { $out } "$pre$key$num=$data\n";
    }
    else {
        $num++;
        print;
    }
}
__DATA__
    name=elephant
    ParameterFromBook=234
    name=star.world
    ParameterFromBook=200
    name=home_room1
    ParameterFromBook=264

However, if you just wanted to give the key it's particular count. This is enough:

my %occur;
while ( <$in> ) {
    my ( $pre, $key, $data ) = m/^(\s*)(\w+)=(.*)/;
    $occur{$key}++;
    print { $out } "$pre$key$occur{$key}=$data\n";
}
Axeman
+1 : Sane code.
Kent Fredric
+1  A: 

It can be condensed to a one line perl script pretty easily, though I don't particularly recommend it if you want readability:

#!/usr/bin/perl
s/(.*)=/$k{$1}++;"$1$k{$1}="/e and print while <>;

This version reads from a specified file, rather than using the command line:

#!/usr/bin/perl
open IN, "/tmp/file";
s/(.*)=/$k{$1}++;"$1$k{$1}="/e and print while <IN>;
pdehaan
what you mean about readability: (its not reliable script?)
lidia
its work fine ( but I need to know if this script is believable)please your advice lidia
lidia
what I need to change if I want to put the PATH : /tmp/filein plcae to give argument to the script?
lidia
By readability I mean the script may not be easy to understand if you're unfamiliar with perl.I'm not sure I understand your other question.
pdehaan
the second question is that I don't want to use argument , I need to set the PATH=/tmp/file , in order the script will read from file and not from the argument , please help
lidia
edited to include what you were asking about
pdehaan
final remark can you please advice how to write the output to somefile?lidia
lidia
@pdehann : its hard to understand even if you DO understand Perl, mostly because of the massive terseness you've needlessly employed. Also, 1) use '`open my $fh`' not '`open IN`' ( lexical file handles ) 2) use 3-arg-open ( `open my $fh, '<', '/tmp/file'` ) 3) check for open failure ( `open my $fh, '<' , '/tmp/file' or die $@;` )
Kent Fredric