d5e5 109 Master Poster

its not working ....

If you wanted to retrieve the highest score you would use offset of 0 (not 1). And so to retrieve the 6th highest score you need an offset of 5.

SELECT id FROM members ORDER BY score desc LIMIT 5, 1;

In English I think the above says something like, "skip the first five rows and then retrieve one row."

d5e5 109 Master Poster

The input record separator (see perlvar) determines how much input to read for each input record. It is newline by default. Change it to semicolon followed by newline and each time perl reads the file it will read up to the next semicolon followed by newline, which is what you want.

#!/usr/bin/perl
use strict;
use warnings;

$/ = ";\n";#Now semicolon followed by newline character indicates end of input rec

while (<DATA>){
    chomp;
    my ($name, $value) = split(/=/);
    print "$name => $value\n";
}

__DATA__
variable=value;
variableX=value value

value value value

value

;
variable2=value2;
d5e5 109 Master Poster

...I'm getting this warning message:

could not find ParserDetails.ini in /usr/lib/perl5/site_perl/5.8.8/XML/SAX

Is this related?

Maybe not. The Perl-XML FAQ suggests it may have to do with how XML::SAX was installed on your computer. I don't know about this but the FAQ suggests re-installing XML::SAX and "if you are asked whether ParserDetails.ini should be updated, always say yes."

d5e5 109 Master Poster

thank you, that solved my problem. i have another problem.
lets say i randomly pick some company, i add up their total amount, i get 17259. but you don't know which companies i choose to get this number. how do you find out? is that possible to use combination to get it?

For sake of clarity and searching the forum topics, when you have another question you should start another thread. However, I can tell you I can't think of any way to know which companies' amounts you chose to add up to 17259 except to ask you.

d5e5 109 Master Poster

If you don't want to insert your data into a database first, you could read them into a hash, adding the amounts as you do so.

#!/usr/bin/perl
use strict;
use warnings;

my %payments;
while (<DATA>){
    chomp;
    my ($eid, $date, $amount) = split;
    next if m/^\D/; #Skip header line (starts with non-digit character)
    my $key = $eid . ' ' . $date;#Build key for groups to sum
    $payments{$key} = 0 unless exists($payments{$key});
    $payments{$key} += $amount;
}

print "eid   date\t\tamount\n";
foreach my $key(sort keys %payments){
    print "$key\t$payments{$key}\n";
}

__DATA__
eid date amount
00101 2009-12-21 3009
00101 2009-12-21 165
00101 2009-12-29 235.5
00201 2009-12-17 2583
00201 2009-12-17 394.5
00301 2009-12-29 3738
00401 2009-12-17 2244
00501 2009-12-24 2851.5
00601 2009-12-17 19450.5
00701 2009-12-17 15240
00801 2009-12-17 11277
00901 2009-12-21 16056

This gives the following output:

eid   date		amount
00101 2009-12-21	3174
00101 2009-12-29	235.5
00201 2009-12-17	2977.5
00301 2009-12-29	3738
00401 2009-12-17	2244
00501 2009-12-24	2851.5
00601 2009-12-17	19450.5
00701 2009-12-17	15240
00801 2009-12-17	11277
00901 2009-12-21	16056
d5e5 109 Master Poster

I recommend installing the DBI and SQLite modules for perl and inserting your data into a database table as follows:

#!/usr/bin/perl
use strict;
use warnings;

use DBI;

# Connection to DB file created before
my $dbh = DBI->connect("dbi:SQLite:dbname=demo.db","","");

$dbh->do("CREATE TABLE payments (eid,date,amount)");
 
my $sth = $dbh->prepare("insert into `payments` (eid,date,amount) values (?, ?, ?)")
             or die "prepare failed: " . $dbh->errstr();  

while (<DATA>){
    chomp;
    my ($eid, $date, $amount) = split;
    $sth->execute($eid, $date, $amount) or die "execute failed: " . $sth->errstr(); 
}

# Close connection
$sth->finish();
undef($dbh);

__DATA__
00101 2009-12-21 3009
00101 2009-12-21 165
00101 2009-12-29 235.5
00201 2009-12-17 2583
00201 2009-12-17 394.5
00301 2009-12-29 3738
00401 2009-12-17 2244
00501 2009-12-24 2851.5
00601 2009-12-17 19450.5
00701 2009-12-17 15240
00801 2009-12-17 11277
00901 2009-12-21 16056

After doing this, writing queries to select and summarise the data in various ways will be straightforward, once you learn a few simple SQL statements.

d5e5 109 Master Poster

I suggest that the part of your code that loops through the lines should look more like this:

my $counter = 0; #Number of lines you want to print

while (<INPUT>){
    $counter = 2 if m/FrNum: 1 /;
    if ($counter > 0){
        print;
        $counter--;#Subtract 1 from your counter
    }
}
d5e5 109 Master Poster

Tell us what you mean by not working. Do you get a syntax or runtime error, or does it print too many lines or nothing at all?

Give us an example that's easy to test. You don't want to have to type the name of the file every time you test your script, do you? Once you know the file-prompting portion of your script works, set it aside and make a testable snippet of the record-matching and printing part of the script so you can test it repeatedly and debug it.

I see at least one problem in your script:

my  $next1;#Declare variable
#Do other things
#...
#$next1 still has no value
$_     = $next1;#Wipe out the current record by assigning no value. Why?
print "$_";#Print nothing?
print "$next1.\n";#Print nothing followed by period followed by newline?
d5e5 109 Master Poster

but this makes me think that that's why I SHOULD use english..it's gonna be easier to write SQL queries where most of the command is gonna be in 1 language, I don't see why there should be a conflict.. :?:

I would say definitely avoid using SQL reserved words to name tables and columns. I've seen examples posted here where the table is named `table` and one of the columns that happens to have a DATETIME type is called `datetime`. I find that confusing, to say the least.

However, I would rather use names consisting of non-accented characters with an English-like spelling for ease of typing and remembering the correct spelling, because my first language is English and my usual keyboard layout is US English.

d5e5 109 Master Poster
#!/usr/bin/perl
use strict;
use warnings;

my $pp_replaced = 0;#Indicates no occurrence of PP has been replaced yet
while(<DATA>){
    if (m/^PP:/ and $pp_replaced == 0){
        s/PP:/HL:/;
        $pp_replaced++;#Add 1
    }
    print;
}
__DATA__
PP: Happy Sunday!
PP: It's a good weather.
PP: Have a blessed Sunday everyone.
d5e5 109 Master Poster

I don't think I know how to help you without more information.

Can you give us examples of these booking reference numbers? Do you want to look up one booking reference at a time, or match a range or pattern of them with one query? Give us an example of what you want to search for and examples of what should match and not match that pattern.

I don't see why you can't use regular expressions to search for numbers, although, depending on what you want to do, there may be other ways to do it. What is this "brick wall" you speak of?

d5e5 109 Master Poster
select count(*) from (select 1 from t1 UNION ALL select 1 from t2) as both_tables;
d5e5 109 Master Poster
update test set barcode = CONCAT('PK_',barcode,'_ZZ');
d5e5 109 Master Poster

But what if this child contains multiple nodes as below:
<child>
<details>
<name/>
<education>
</details>
</child>

For multiple levels of tags I don't think you can use XML::CSV as it says in the description of the docs "XML::CSV ... currently ... only allows a simple XML structure." Maybe someone else can help you with creating a multiple level structure. It would help if you could show us a sample of your csv input data.

d5e5 109 Master Poster

Assuming an input file such as example.csv (contains no accented or non-ascii characters)

fname,lname
bugs,bunny
donald,duck
betty,boop

You could use XML::CSV in a script such as the following:

#!/usr/bin/perl
use strict;
use warnings;
use 5.010;

use XML::CSV;
my $csv_obj = XML::CSV->new();
$csv_obj->parse_doc("example.csv", {headings => 1});#file starts with header row
$csv_obj->print_xml("output.xml",
                    {format => " ",
                     file_tag => "children",
                     parent_tag => "child"});

output.xml now contains:

<children>
 <child>
  <fname>bugs</fname>
  <lname>bunny</lname>
 </child>
 <child>
  <fname>donald</fname>
  <lname>duck</lname>
 </child>
 <child>
  <fname>betty</fname>
  <lname>boop</lname>
 </child>
</children>
d5e5 109 Master Poster

Sorry, I meant my @left = Exception::excep(\@array,\@toexcept,$number,$n); not Exception->excep After fixing the above errors your script will still fail with at least one other runtime error. I haven't found all of them. Have a look at http://perldoc.perl.org/perlfaq3.html#How-do-I-debug-my-Perl-programs? for tips on debugging Perl scripts.

d5e5 109 Master Poster

The last statement in the Exception module should return a value of 1 because the use command requires a value of 1 to indicate the successful loading of the module. my @left = &excep(\@array,\@toexcept,$number,$n); The above tries to call a subroutine in the main package rather than Exception. You need either to specify Exception->excep or import the excep method into your main package.

d5e5 109 Master Poster

Comparing this line my ($ref_numbers,$ref_exceptions,$number,$n) = @_; with if($i != $$ref_execptions[$number]) It looks like a typo in $$ref_execptions.

d5e5 109 Master Poster
#!/usr/bin/perl
use strict;
use warnings;
use 5.006;

my @your_files = qw(google_20110225091600.7z
google_20110225091622.7z
google_20110225100306.7z
google_20110225100410.7z
google_20110225104833.7z
google_ready_20110225100410.txt
google_ready_20110225104833.txt
Yahoo_20110225091639.7z
Yahoo_20110225100320.7z
Yahoo_20110225100424.7z
Yahoo_20110225104849.7z
Yahoo_ready_20110225100424.txt
Yahoo_ready_20110225104849.txt
Community_20110225091637.7z
Community_20110225100318.7z
Community_20110225100422.7z
Community_20110225104848.7z
Community_ready_20110225100422.txt
Community_ready_20110225104848.txt);

my @keys = ("20110225104849","20110225104833","20110225104848");
my $pattern = join '|', @keys;# Result: 20110225104849|20110225104833|20110225104848
print "You do not want to delete files matching this pattern:\n$pattern\n\n";
print "You DO want to delete the following files:\n";

#For testing I substituted 'print' for 'unlink'
#When you're sure it works correctly replace with
#do { unlink if ( !/$pattern/ ) } for @your_files;
do {print "$_\n" if ( !/$pattern/ )} for @your_files;
d5e5 109 Master Poster

Hi,

Thanks for your help...i got the output. thanks for your coding

You're welcome. Please don't forget to mark this thread 'solved'.

d5e5 109 Master Poster

The following works for me. my $this_url = $cgi->url(); Don't put anything between the parentheses. You put the full path to your script file and Apache doesn't understand that. The $cgi->url() method should retrieve the correct url for the script that you are running, so that when you submit your form it should go to the same script containing that form. You can read about this at OBTAINING THE SCRIPT'S URL

d5e5 109 Master Poster
#!/usr/bin/perl
use strict;
use warnings;

use CGI qw(:all);

#Create a new CGI object
my $cgi = new CGI;
my $this_url = $cgi->url(); #Save this script's url
my $first = $cgi->param('first_name');
my $last = $cgi->param('last_name');

print "Content-type:text/html\n\n";
print <<EndOfHTML;
<html><head><title>Generating Self-Referential URLs</title></head>
<body>
<FORM action="$this_url" method="POST">
First Name: <input type="text" name="first_name">  <br>

Last Name: <input type="text" name="last_name">

<input type="submit" value="Submit">
</FORM>
<p>The name you entered was '$first $last'</p> 
</body>
EndOfHTML
#Put a comment or linefeed after EndOfHTML
#Otherwise perl might not find it.
d5e5 109 Master Poster
do { unlink if ( !/20110225104849|20110225104833|20110225104848/ ) } for @your_files;

I like Muthu's answer and it works, but BE CAREFUL when testing it that you glob the desired directory into your array. You don't want to delete all the files in whatever your current working directory happens to be!

#!/usr/bin/perl
use strict;
use warnings;
use 5.006;

my @your_files = <temp/*>;

#Comment out the following line the first time you test this.
#You want to make sure that @your_files contains files from the [I]desired[/I] directory.
#Otherwise you may delete all files in some other directory!!!
#do { unlink if ( !/20110225104849|20110225104833|20110225104848/ ) } for @your_files;

print "$_\n" foreach @your_files;
d5e5 109 Master Poster

Hi to all,
i created following table in SQL.
===================================

create table employee(name varchar(20), dob date)

===================================

But, when i ran the query, i got the massage that 'SQL can not find data type 'date''.
How should i include 'date' in to table definition.

create table employee(name varchar(20), dob date) should have worked OK in MySQL. What database software were you using when you got that error?

d5e5 109 Master Poster
#!/usr/bin/perl
use strict;
use warnings;

while (<DATA>){
    my ($fruit,$end)=split(/\_ #Match an underscore
                           (?!.*\_) #Negative lookahead.
                                    #Match only if not followed by characters
                                    #followed by another underscore
                           /x);     #x means allow multi-line regex with comments
    print "My fruit = $fruit\n";
    print "My end = $end\n";
}
__DATA__
apple_india_20110218091255.txt
apple_india_20110221112444.txt
apple_india_20110301112444.txt

http://www.regular-expressions.info/lookaround.html

d5e5 109 Master Poster

Yes I admit perl compiles the program to an internal form before running it. I meant that the perl programmer just writes a script and gets perl to run it, without having to learn how to compile it before running it. I agree it makes sense to think of perl as a hybrid compiler/interpreter because if the script has a syntax error the internal compile step fails and the perl will not run the script. The programmer needs to know the difference between syntax errors and runtime errors, which does arise from the compile vs. run distinction.

As for an environment in which to write and test scripts, I think lots of programmers write scripts in a text editor and run them from the command prompt. The command prompt is also referred to as a 'shell' I believe.

When I started learning Perl a few years ago I used Komedo Edit made by the same company that distributes ActiveState perl. Komedo Edit is a program editor which highlights Perl commands and key words, helps with indentation of blocks, etc. and does some syntax checking. It also let's you run the script from the editor. I don't know if it would work the same with Strawberry Perl, but if not there must be plenty of other free program editors with similar features.

You may want to try Googling for perl program editor free windows .

**Edited
Regarding how to step through a script and change things …

d5e5 109 Master Poster

I'm not a gamer, rarely use Vista and don't have Strawberry Perl so maybe that's why I don't understand the question. To clarify, are you saying you have downloaded Strawberry Perl (source? or binary?) and need instructions how to install it in Windows Vista?

You ask how to compile and run the scripts but Perl is an interpreter that runs scripts written with a text editor. You don't do anything to compile them before running them.

To run a script, just start a Command Prompt (search all programs in Vista for Command Prompt) and type perl myscript.pl where myscript.pl is the name (including the path, if not in your current working directory) of the perl script you want to run. I don't think people call the Command Prompt MS-DOS anymore, but it lets you run the usual DOS commands like cd, dir, del, copy etc.

d5e5 109 Master Poster

Thank you so much for your help, it worked. (Although, the files were being saved as "MyFile..png", but that was easily fixed by removing the extra period from the file saving section.)

Once again, you've been amazing in both your speedy replies, and great help.

Thanks,
Liam.

You're welcome. I didn't want to test the full script as it involved saving a lot of files so the suggestions were kind of hit and miss, but I'm glad it works now. Please don't forget to mark this thread solved.

d5e5 109 Master Poster

Please accept my condolences for your loss.

I think the remaining problem consists in the lexical (i.e. declared with my and limited in scope to the current block or subroutine) $ext variable going out of scope at the point where you name and save the file. Try the following: move the my $ext; from the subroutine and put it near the beginning of your program, where it will have the widest scope. You could put it immediately before the #Set specifics comment, for example, like this:

## Bugs ##

# Files that aren't a png, are being saved as one.
my $ext; #Declare variable to store file extension until file is saved.

# Set Specifics
# etc.
#.

Make sure the my $ext; occurs only once in your program. The script should really start with use strict; use warnings; as nearly all Perl scripts should.

d5e5 109 Master Poster

Do you want to interpolate the variables before inserting the data into the table, or after reading it from the table? Or does it matter? Can we assume the value of $x is the same when inserting the record as when retrieving it?

I don't know how to accomplish the latter (reading a database record and recognising and evaluating parts of a string field as embedded Perl variables.) I would guess it involves searching for another module on CPAN to do it.

d5e5 109 Master Poster

After creating and populating the @printarray, connecting to MySQL, selecting a database etc. the following snippet seems to work OK. The trick is to prepare your query with placeholders and letting DBI worry about what characters need escaping.

$sth=$dbh->prepare
             ("INSERT INTO test (id, html_string)
               VALUES           (? , ?)");

my ($id, $html);

$id = 1; #Or any unique integer
$html = join '', @printarray; #concatenate array elements into string with no separator
$sth->execute($id, $html) 
    || die "Couldn't insert record : $DBI::errstr";

Placeholders

d5e5 109 Master Poster

It is confusing to name a column 'date' because DATE is a datatype. The creator of the table should have created a DATE type column with a better name. If you have no choice but to try and sort this table without altering the design, try the following:

mysql> select * from test ORDER BY STR_TO_DATE(date, '%d-%M');
+-----------+-------+-----+
| date      | Name  | id  |
+-----------+-------+-----+
| 14_March  | Anwar | 145 | 
| 14-July   | Krish |  17 | 
| 22-August | Ram   |  15 | 
+-----------+-------+-----+
d5e5 109 Master Poster

It sets scope:

my $var1="world";
{
	my $var1="hello";
	print "$var1 ";
}
print "$var1\n";

Output:

hello world

Good answer. If you want to read more I strongly recommend Coping With Scoping which explains in simple language with examples the difference between variables declared with my and package, or global, variables.

d5e5 109 Master Poster

Save and remove the $ARGV[1] argument from the @ARGV array (using the pop function) before enabling inplace editing. Then inplace editing can proceed because the only argument remaining in @ARGV is the name of the file you want to edit.

#!/usr/bin/perl
use strict;
use warnings;

my %found; #Keep track of flags found in file;

if (@ARGV != 2) { 
      die "Usage: $0 filename dir\n"; 
}

my $carbon_flags_dir = pop; #Remove $ARGV[1] from @ARGV and assign to variable
print "The folder containing text files of carbon flags is: $carbon_flags_dir\n";
#
#Do your opendir, read text files, push flags into your @carbon_flags here
#before enabling inplace editing
#

#Enable inplace editing. Copy of input file saved as 'test.hrh.bk'
$^I = ".bk";

my $end_flag = '#endif  // __BLDSERVICESSOFTWARE_HRH';
my $end_flag_regex = qr($end_flag);

#Read file into array line by line until line matches end flag
my @file = ();
while (<>) {
    chomp;
    
    if (m/$end_flag_regex/) {
        # edit and print lines
        my @processed_file = edit_lines(@file);
        push @processed_file, $_;
        # last chance to print before ARGVOUT gets reset
        print join "\n", @processed_file;
        @file = ();
    }
    else
    {
        push @file, $_;
    }
}

sub edit_lines{
    my @f = @_;

    #The following is a list of flags to add or change
    my @check = qw(FF_HERE_AND_NOW_COMPONENT FF_WEB_SEARCH_COMPONENT);
    
    foreach my $chk(@check){
        foreach my $line(@f){
            if ($line =~ s/^#(define|undef)(\s$chk)/#define $2/){
                $found{$chk}++;
            }
        }
    }
    
    push @f, "#Add the flags not found\n";
    foreach my $chk(@check){
        push @f, "#define $chk" if not exists $found{$chk};
    }
    return @f;
}
d5e5 109 Master Poster

Hi d5e5,

Thanks for your response..i will try to make it possible and will let you know but for the time being i have one more question related to writing data in text file..

I am writing a data in text file through perl and i am using perl formatting to write the data now when i run the code the columns header also write every time in a text file i only want to disply the column header only one time and after that when ever i execute my perl script only columns values print into a text file. that file will act as a history data
Can you pls help me out with this...?

Thanks

Test if the file you want to write to exists, if it does not exist then you want to write a header, otherwise you do not want a header. To prevent the write command from writing a header, declare an empty format that will write nothing as a header, select the filehandle to which you want to write and set the value of $^ to the name of the empty format.

#!/usr/bin/perl
use strict;
use warnings;
use 5.010;

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
$year = $year + 1900;
$mon = $mon + 1;
my $yymmdd = "$year-$mon-$mday";
my $hhmnss = "$hour:$min:$sec";
my $grp;
my $jc;

my $header_wanted = 0; # 0 means false, 1 means true
my ($date_hdr, $time_hdr, $jg_hdr, $tj_header) = ('Date', 'Time', 'Job Group', 'Total Jobs#');

format STDOUT_TOP =
@<<<< …
d5e5 109 Master Poster

I've haven't used format to write from Perl yet (I am only an amateur in Perl.) I'll look it up in perldoc when I get a chance, but meanwhile please ask that question as a new thread. Maybe somebody else who knows the answer will notice the question if they see it as a title for a new thread.

d5e5 109 Master Poster

Hi d5e5,

I have searched out and find that a perl Module Spreadsheet::ParseExcel allow us to append data in an excel file although i have tried so many times but i am unable to get any usefull results.
Do you have any idea that how i can do append data using Spreadsheet::ParseExcel module...?

Thanks

Sorry, I really don't know. I don't even have Excel software on my computer.

Are you sure that you have to append data to your spreadsheet? Why not save your data in a database or even a text file which your Perl program can read and process to create a new spreadsheet with all the historical and new data? I am not an expert with Excel but it seems to me that having Perl save and process data in database or text files and then creating a new spreadsheet for users to view would be simpler than having Perl save, read and modify an existing Excel worksheet.

Maybe I don't understand your requirements but it seems that the Excel spreadsheet can be useful for viewing or presenting your output, but not for saving or processing it.

d5e5 109 Master Poster

Hi Dave

They are not the same.

It seems to me that the argument containing the file name you want to edit will need to include the correct absolute path. I see in the original Ant target that you posted you had a line like this: <arg value="${build.drive/variant.confml"/> Is that correct? Try adding that to the Ant target that runs the simple test script in my previous post so it can print out the value of the argument(s) and see if the script receives the correct path and file name for the file name that the real script would edit.

d5e5 109 Master Poster

First I created the following target to run the script from Ant

<target name="run-perl-script">
		<exec executable="perl">
		<arg value="${common.tools}/call_perl_script.pl"/>
		</exec>
		</target>

Then called the target:

E:\Build_E\running\idos\ssdo\branches\mcl-zipsci>hlm -Dbuild.drive=X: -Dbuild.number=1 -Dbuild.system=sbs-ec run-perl-script

Output on screen:

Buildfile: build.xml
     
run-perl-script:
     [exec] Perl v5.10.0 required--this is only v5.6.1, stopped at E:/BUILD_E/running/idos/ssdo/common_tools/call_perl_script.pl line 4.
     [exec] BEGIN failed--compilation aborted at E:/BUILD_E/running/idos/ssdo/common_tools/call_perl_script.pl line 4.
     [exec] Result: 255

My system runs on Perl 5.6.1

Please try running the following modified test script from an Ant target:

#!/usr/bin/perl
use strict;
use warnings;
use 5.006_001;

use Cwd;
my $cwd = getcwd();
# I add !!!! so we can see if any spaces, etc.
print "\nCurrent working directory is: $cwd\n";
print "Ant called $0 with the following arguments:\n";
print join "!!!!\n", @ARGV, "\n";

I'm wondering if the directory in which Ant runs the script is different than the one from which you started Perl when testing the script from the command line?

d5e5 109 Master Poster

Thanks David

This script now works perfectly.
However, I noticed that there is no way I could use this by calling from an Ant target, with arguments.

For example, I want to call the script from within an Ant target:

<target name="update-flag">
	<!--update flags-->
   <exec executable="perl">
	<!-- Script that updates the flags -->
	<arg value="${common.tools}/update_carbon_flags.pl"/>
	<!-- Name of the file which should be updated -->
	<arg value="${build.drive/variant.confml"/>
	<!-- Directory wherefrom the flags should be parsed -->
	<arg value="${ccm.project.wa_path}"/>
    </exec>
</target>

But as you mentioned, the script will take whatever arguments it is fed with and process those as file arguments - I guess it cannot be used in the above scenario?

I don't have Ant or Java and have never used them for development so I don't know whether inplace editing will work when called from an Ant target. I guess it depends on what the arguments look like when Ant adds them. How about running a simple test script like the following to see if Ant can call a Perl script and to see the format and values of the arguments that Ant passes. Try calling the following script from your Ant target:

#!/usr/bin/perl
use strict;
use warnings;
use 5.010;

# I add !!!! so we can see if any spaces, etc.
say "Ant called $0 with the following arguments:";
say join "!!!!\n", @ARGV;
d5e5 109 Master Poster

I haven't used Spreadsheet::WriteExcel, just installed it to test that it can be installed on Linux without root permissions. The documentation that comes with it says

This module cannot be used to write to an existing Excel file (See
"MODIFYING AND REWRITING EXCEL FILES").

d5e5 109 Master Poster

Hi Shibblez,

Thanks for your response...
i have used Spreadsheet::WriteExcel but it is giving me an error that WriteExcel.pm does not exist @INC more over i cannot install any additional software or patch on Linux Machine...Well i first i want to generate an excel file on linux after that i will transfer file using ftp or SFTP from Linux to Windows.

What do you think FTP will work out or not..?

Thanks

If you can copy your script to the Linux server it seems to me you can install Spreadsheet::WriteExcel to that server. As a test, I just used CPAN Minus to install Spreadsheet::WriteExcel on my Ubuntu 9.10 system as a non-root user and I didn't have to use sudo.

david@david-laptop:~$ cpanm install Spreadsheet::WriteExcel
install is up to date. (0.01)
--> Working on Spreadsheet::WriteExcel
Fetching http://search.cpan.org/CPAN/authors/id/J/JM/JMCNAMARA/Spreadsheet-WriteExcel-2.37.tar.gz ... OK
Configuring Spreadsheet-WriteExcel-2.37 ... OK
==> Found dependencies: OLE::Storage_Lite, Parse::RecDescent
--> Working on OLE::Storage_Lite
Fetching http://search.cpan.org/CPAN/authors/id/J/JM/JMCNAMARA/OLE-Storage_Lite-0.19.tar.gz ... OK
Configuring OLE-Storage_Lite-0.19 ... OK
Building and testing OLE-Storage_Lite-0.19 ... OK
Successfully installed OLE-Storage_Lite-0.19
--> Working on Parse::RecDescent
Fetching http://search.cpan.org/CPAN/authors/id/D/DC/DCONWAY/Parse-RecDescent-1.965001.tar.gz ... OK
Configuring Parse-RecDescent-1.965001 ... OK
Building and testing Parse-RecDescent-1.965001 ... OK
Successfully installed Parse-RecDescent-1.965001
Building and testing Spreadsheet-WriteExcel-2.37 ... OK
Successfully installed Spreadsheet-WriteExcel-2.37

Also have a look at How do I keep my own module/library directory?

d5e5 109 Master Poster

You must select the database that contains the objects to which the rest of the SQL statements refer. For example, if the statements in your company_data.sql refer to objects in a database called 'db1' you need to either run the following statement

USE db1;

before running source from the company_data.sql or else add that statement to the beginning of your company_data.sql file.
http://dev.mysql.com/doc/refman/5.0/en/use.html

d5e5 109 Master Poster

Sorry, I should have sent you the entire script. My point was that copying a file name from $ARGV[0] and pushing it back into @ARGV is wrong. The result is you have two elements in @ARGV for the same file name so the inplace edit gets all messed up when it tries to rename the same file and reopen the same file twice. Don't do that unless you are NOT passing the file name on the command line as an argument. Pushing a file name into @ARGV is just a trick to use inplace editing without passing an argument on the command line. Here is the script that works for me:

#!/usr/bin/perl
use strict;
use warnings;

my %found; #Keep track of flags found in file;

if (@ARGV == 0){
    my $filename = 'test.hrh';
    #So you can use diamond operator and inplace editing
    push @ARGV, $filename;
    warn "No file name argument so I assume you want to edit $filename.\n"
}

#Enable inplace editing. Copy of input file saved as 'test.hrh.bk'
$^I = ".bk";

my $end_flag = '#endif  // __BLDSERVICESSOFTWARE_HRH';
my $end_flag_regex = qr($end_flag);

#Read file into array line by line until line matches end flag
my @file = ();
while (<>) {
    chomp;
    
    if (m/$end_flag_regex/) {
        # edit and print lines
        my @processed_file = edit_lines(@file);
        push @processed_file, $_;
        # last chance to print before ARGVOUT gets reset
        print join "\n", @processed_file;
        @file = ();
    }
    else
    {
        push @file, $_;
    }
}

sub edit_lines{
    my @f = @_;

    #The following …
d5e5 109 Master Poster

But the file name is coming from another place as an argument as $ARGV[0];

Muthu is correct. If @ARGV contains at least one element (no matter where it comes from) then trying to copy the value of $ARGV[0] and pushing it back into @ARGV will mess up what Perl is trying to do. If you want to run the script with the filename argument already in @ARGV then modify it as follows:

#!/usr/bin/perl
use strict;
use warnings;

my %found; #Keep track of flags found in file;

if (@ARGV == 0){
    my $filename = 'test.hrh';
    #So you can use diamond operator and inplace editing
    push @ARGV, $filename;
    warn "No file name argument so I assume you want to edit $filename.\n"
}

#Enable inplace editing. Copy of input file saved as 'test.hrh.bk'
$^I = ".bk";
#...
#...
#...
d5e5 109 Master Poster

Some of the programmers at StackOverflow have told me that when doing an inplace edit, reading all the lines into an array all at once is bad, because the file gets closed before I get a chance to print to it. Please try the following, hopefully it works better:

#!/usr/bin/perl
use strict;
use warnings;

my %found; #Keep track of flags found in file;

my $filename = 'test.hrh';
#So you can use diamond operator and inplace editing
push @ARGV, $filename;
#Enable inplace editing. Copy of input file saved as 'test.hrh.bk'
$^I = ".bk";

my $end_flag = '#endif  // __BLDSERVICESSOFTWARE_HRH';
my $end_flag_regex = qr($end_flag);

#Read file into array line by line until line matches end flag
my @file = ();
while (<>) {
    chomp;
    
    if (m/$end_flag_regex/) {
        # edit and print lines
        my @processed_file = edit_lines(@file);
        push @processed_file, $_;
        # last chance to print before ARGVOUT gets reset
        print join "\n", @processed_file;
        @file = ();
    }
    else
    {
        push @file, $_;
    }
}

sub edit_lines{
    my @f = @_;

    #The following is a list of flags to add or change
    my @check = qw(FF_HERE_AND_NOW_COMPONENT FF_WEB_SEARCH_COMPONENT);
    
    foreach my $chk(@check){
        foreach my $line(@f){
            if ($line =~ s/^#(define|undef)(\s$chk)/#define $2/){
                $found{$chk}++;
            }
        }
    }
    
    push @f, "#Add the flags not found\n";
    foreach my $chk(@check){
        push @f, "#define $chk" if not exists $found{$chk};
    }
    return @f;
}
d5e5 109 Master Poster

Take for example the test.hrh file you posted at the beginning of this thread. The following tries to read it all into an array (and for some reason closes it, although I didn't want to close it), then loops through the array of flags to check and modifies the array, then prints the array to test.hrh. Because it is an inplace edit, it creates a backup file named test.hrh.bk.

#!/usr/bin/perl
use strict;
use warnings;

my %found; #Keep track of flags found in file;

#The following is a list of flags to add or change
my @check = qw(FF_HERE_AND_NOW_COMPONENT FF_WEB_SEARCH_COMPONENT);

my $filename = 'test.hrh';
#So you can use diamond operator and inplace editing
push @ARGV, $filename;
#Enable inplace editing. Copy of input file saved as 'test.hrh.bk'
$^I = ".bk";

my @file = <>; #Read all records into array
chomp(@file);

foreach my $chk(@check){
    foreach my $line(@file){
        if ($line =~ s/^#(define|undef)(\s$chk)/#define $2/){
            $found{$chk}++;
        }
    }
}

push @file, "\n\n#Here's the tricky part.\n#Let's try to add the flags not found\n";
foreach my $chk(@check){
    push @file, "#define $chk" if not exists $found{$chk};
}

#I didn't know that reading all records of the file would close it,
#but it did... so I have to open it for output.
open ARGVOUT, '>', $filename or die "$!";#Open empty file of same name for output
print ARGVOUT join "\n", @file;
close ARGVOUT;
d5e5 109 Master Poster
#!/usr/bin/perl
use strict;
use warnings;

use constant {SECONDS_IN_DAY => 86400};
use HTTP::Date qw(time2str str2time parse_date);

my $today_YMD = epoch2YMD(time);
my $today_epoch = str2time($today_YMD);
my $today_minus_3_epoch = $today_epoch - 3 * SECONDS_IN_DAY;
my $today_minus_3_YMD = epoch2YMD($today_minus_3_epoch);
my (@completed, @not_completed);

my $filename = 'omar.txt';
open my $fh, '<', $filename or die "Failed to open $filename: $!";

while (<$fh>){
    chomp;
    my @rec = split(/\|/);
    my $jobdt = epoch2YMD(str2time($rec[0]));
    if ($jobdt lt $today_minus_3_YMD){
        push @not_completed, \@rec;
    }
    else{
        push @completed, \@rec;
    }
}
#use Data::Dumper;
#print Dumper(\@not_completed);
print "Total successful jobs = " . scalar(@completed) . "\n";
print "Total failed jobs = " . scalar(@not_completed) . "\n";
print "Name of Failed jobs are: ";

my @arr;
foreach (@not_completed){
    push @arr, @{$_}[2];
}
print join(', ', @arr);

sub epoch2YMD{
    #Converts epoch datetime number (seconds since beginning of epoch)
    #Drops time portion and returns date-only string as YYYY-MM-DD
    my $epoch = shift;
    die "Usage is epoch2YMD(epoch)" unless ($epoch);
    my $today_YMD = substr(parse_date( localtime($epoch)),0,10);
}

Output today (Tue, Feb 1) is:

Total successful jobs = 11
Total failed jobs = 18
Name of Failed jobs are:  ABC,  DEF,  GHI,  JKL,  LMN,  OPQ,  RST,  UVW,  XYZ,  MVU,  QPO,  CBD,  ASR,  QWY,  CXZ,  FNB,  VXR,  CDS
d5e5 109 Master Poster

Is that for editing only?
How about adding strings, lines if required?

Print whatever you want to the file. As I said, all inplace edit does is rename the original file and let you read it, then whatever you print goes into a new file that has the original file name. That's all. If you do an inplace edit of a file and don't print anything, the result is an empty file. Or you can edit a file containing 5 lines, replace those lines (by printing 5 different lines), or delete them (by not printing them) or add 100 new lines (by printing 100 lines of whatever you want).

d5e5 109 Master Poster

Getting back to David,
Can multiple strings be replaced using the inline edit option?
Lets says the flags are store in an array?

Any help?

Yes. Inplace (AKA inline) editing of a file opens whatever filename it finds in @ARGV, lets you read it any way you want (one line at a time, all lines at once into an array, or slurping entire file into a string -- it doesn't matter which) and lets you print the contents back to the same file after you make any changes that you want.

The trick with editing a file inplace is to push the filename into the @ARGV array and then read from the empty <> operator and just print the edited contents without specifying a filehandle. In effect inplace editing just renames or moves the original file to a backup file and creates a new file with the original file name which you print data to by print statements that do NOT specify a filehandle.