d5e5 109 Master Poster

In your loop that builds your string, replace the following statement: $string .= $_; with these:

chomp; #Removes trailing new-line character from $_
    $string .= "$_ "; # "$_ followed by one space"

http://perldoc.perl.org/functions/chomp.html

Hi,

I have a file.txt, I need to enter the data in string. Currently my code looks like this,

#!/usr/bin/perl

open myfiles, "file.txt" or die "couldn't find file: $!";

while (<myfiles>){
   $string .= $_;     
}     
print $string;
close(myfiles);

The output when I print the string is like

hello.c
work.c
office.c

Is it possible to get the output of the string ot be in 1 line with spaces such as

hello.c work.c office.c

If there is a was which can place the data in the string initially like this or if there is a way I can manipulate the string it will be really helpful.

Thanks,
Rahul

d5e5 109 Master Poster

Hello d5e5

I've already tried that but with no success... And the mentionned script is working when Distinguishedname is encountered in the whole column so I thought it would be pretty easy to adapt it, but I think I was mistaking, 'cause I'm not finding out how to do that !

Any idea ?

If you've gotta working script with a parsing module I'd be glad to try it though ! :o)

Thanks by advance,
Bastien

#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV;
my $dir = '/home/david/Programming/Perl';
my $file = $dir . '/' . 'input-light.csv';

my $csv = Text::CSV->new();

open (my $fh, "<", $file) or die $!;
my @file = <$fh>;
close $fh;

my $str2find = "Distinguishedname";
my $dropcol;
foreach (@file) { #Loop through array 1st time to find index of column to drop
    if ($csv->parse($_)) {
        my @columns = $csv->fields();
        my $rv = idx (\@columns, $str2find);
        $dropcol = $rv if defined($rv);
    } else {
        my $err = $csv->error_input;
        print "Failed to parse line: $err";
    }
}

foreach (@file) { #Loop through array 2nd time to print data without dropped column
    if ($csv->parse($_)) {
        my @columns = $csv->fields();
        splice (@columns, $dropcol, 1); #Remove column starting at $dropcol for length of 1
        my $status = $csv->combine(@columns);    # combine columns into a string
        my $line   = $csv->string();             # get the combined string
        print "$line\n";
    } else {
        my $err = $csv->error_input;
        print "Failed to parse line: $err";
    }
}

sub idx {#Loop through array, return index of string if found …
BastienP commented: Great response that solved my problem ! +1
d5e5 109 Master Poster

I haven't figured this out yet but I think the first step for something with somewhat complex CSV parsing requirements would be to choose and install a good CSV parsing module for Perl. There are some simple examples of Parsing CSV at this link.

d5e5 109 Master Poster

The brute force approach is maybe not so bad since you don't have to lower the entire dictionary, just the string of its keys.

>>> d = {'Spam': 2, 'Ham': 1, 'Eggs': 3} #Here is a dictionary
>>> s = str(d.keys()) #Here is a string of its keys
>>> 'ham' in s.lower()
True
>>>
d5e5 109 Master Poster

Here's my 2 cents on what (not year%4 and year%100 or not year%400) and True is doing. Python knows it is evaluating a Boolean expression and so it evaluates as much as it needs to, evaluating each component expression according to the rules of precedence, until it get a definite answer to whether the whole expression is true or false. But what it returns seems to be the last component expression evaluated. Accordingly,

>>> 'Boy' and 'Girl'
      'Girl'
>>>

returns 'Girl', not because a girl is more useful than a boy, but because 'Girl' was the last component that needed to be evaluated to determine the value of the whole expression. But that's not all. If instead of 'Girl' we had 3 > 2 the result would be True. Apparently expressions such as 'Girl', 7, etc. will evaluate to True in a Boolean context but otherwise their values are not automatically converted to True or False. But other expressions such as "Fred" > "Barney" are automatically evaluated as Boolean.

>>> 0 and "Genius"
0
>>> 3 < 2 and "Genius"
False
>>>
d5e5 109 Master Poster

I messed that up actually. I did a bit of additional researcha nd realized that it is returning 1 as in "true", meaning there is valid output from the command. I was thinking it was counting the result, but that's not true. I tried a couple of other things like ($result)=print "hello world\n" and that kind of thing. Itis always set to 1, so I suppose it is to indicate that the print command is true. Make sense?

Yes. That must be it. A return of 1 (meaning true) means the print command was successful.

d5e5 109 Master Poster

I agree with mitchems. Just as a further note, the mistake may have included putting the cgi scripts in the same directory as the html documents. Simon Cozens warns against this (even if you succeed in making them executable).

The reason for keeping scripts out of the document hierarchy is to avoid the risk of the source code to our scripts being made available by the web server. ~from Beginning Perl

d5e5 109 Master Poster

Yesterday I was using the perl debugger to test and for some reason it printed the value of $result as blank, indicating zero. But when I run the following script (not using the interactive debugger) the value of $result is 1.

#!/usr/bin/perl
use strict;
use warnings;
my $result = print "hello world\n", 42, "\nhello again world\n", "goodbye world\n";
print $result . "\n";

#Output is:
#hello world
#42
#hello again world
#goodbye world
#1

I am not sure what you mean, mitchems, when you say the result is a count of the output.

d5e5 109 Master Poster

I'm not comfortable with setting up key index columns but I may be able to answer some questions about a hash. With what about the concept of hash are you not comfortable?

The main things you need to know, in order to read a file into a hash are

  • How to declare a hash
  • How to add a key-value pair to a hash and that only scalar keys and values can be stored in a hash
  • How to check if a particular key exists in your hash, and if it does, how to access it
  • How to iterate through your keys so you can access all the key-value pairs

Given a file named b.txt which contains the following:

abcd,abrd,fun,D000,$12,$234,$212,$200,$200,$200
dear,dare,tun,D000,$12.00405,$234.08976,$212.09876,$200,$200,$200

here is an example of how you can read this file into a hash and then iterate through and print the keys and values:

#!/usr/bin/perl -w
use strict;
use warnings;
my $filename_b = '/home/david/Programming/Perl/b.txt';
my %b = %{read_into_hash($filename_b)};

foreach (keys %b) {
    print "The key $_ has $b{$_} as its value\n";
    my $aref = $b{$_};
    print "$b{$_} is a reference to an array containing @{$aref}\n";
}

sub read_into_hash {
    my $file = $_[0];
    my %h = ();
    open (my $fh, '<', $file);
    while (<$fh>) {
        my @fields = split(/,/);
        my $hkey = join(",", @fields[0..3]);
        $h{$hkey} = [@fields[4..9]];
    }
    return \%h;
}
d5e5 109 Master Poster

hi just wanna ask is it possible for perl to get the value of a print command? for ex.

my $result = print "hello world\n";
print "$result\n";

why is it that the "print $result" would print a value which is 1?.. is it possible to get the result "hello world" not 1?... how do i do it?.. help please..

That's weird. I can't explain why print $result would print a value which is 1. The value of $result should be zero (which prints as a blank when unformatted) if the print "hello world\n"; succeeded, and I don't know why it would not.

As for saving whatever you printed: to do that I think you need to redirect your STDOUT to a file.

d5e5 109 Master Poster

Could you attach a copy of data_file_1.dat to your post? Or if you could post some of the data (within code tags) it would make it easier to help you with this.

d5e5 109 Master Poster

The following should edit and save a.config and create a backup copy of the original named a.config.old

perl -pi.old -e 's/(CLUSTER_NAME\t\t)cluster1/$1autocluster/' a.config
d5e5 109 Master Poster

Where in your schema do you record the fact that the student is taking, or has taken some courses? I think you need a table that has a one-many relation associating each student to courses that student is taking or has taken.

StudentCourses (studentid, courseid, date_completed)

d5e5 109 Master Poster

Sorry i made a mistake ,i want to calculate sumbudy years (hw old the person is )using their date of birth (that is located in the column DOB)and the current year.....perhaps (current year - DOB)....i would lyk a sql syntax for that..

If you subtract the year of birth from the current year you sometimes will get the correct age but you may be off by a year. Why? For example, I was born in nineteen fifty-one. 2010 - 1951 = 59. Am I 59 years old? No, because I haven't had my birthday yet this year.

The following query gives a better result.

SELECT	name,
	dob,
	YEAR(CURRENT_DATE)
	- YEAR(dob)
	- CASE WHEN MONTH(CURRENT_DATE)
		> MONTH(dob)
		THEN 0
		WHEN MONTH(CURRENT_DATE)
		< MONTH(dob)
		THEN 1
		WHEN DAYOFMONTH(CURRENT_DATE)
		< DAYOFMONTH(dob)
		THEN 1
		ELSE 0 END AS age
FROM people;

Which gives the following results:

+-----------+------------+------+
| name      | dob        | age  |
+-----------+------------+------+
| Cable Guy | 1951-02-28 |   59 | 
| somebody  | 1974-04-18 |   36 | 
| John Doe  | 1965-07-28 |   44 | 
| David     | 1951-10-01 |   58 | 
+-----------+------------+------+
d5e5 109 Master Poster

You may want to look at http://svn.w4py.org/ZPTKit/trunk/ZPTKit/htmlrender.py I haven't tested it, but it does look like it uses HTMLParser to do what you want.

d5e5 109 Master Poster

...
this is what you sugested however wouldnt the + in this be considered as one or more and the . be conisderd as anying? would you not have to escape it with \

testVar=/^[a-zA-Z0-9._+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/ No, in the above pattern the . is just a dot indicating the possibility of a decimal point. Most symbols, when they appear between square brackets, are interpreted as members of a character class. There are a few exceptions: if ^ is the first symbol after [ then it negates the character class. Hyphen defines a range when it occurs between two letters or between two numbers. When it is the last item in a character class it is just a hyphen. Sometimes escaping a symbol in a character class makes no difference, so I guess you could say "when in doubt, escape." But the above pattern looks OK to me.

d5e5 109 Master Poster

Instead of using separate scalar constants you could use an array of constants that you can iterate through.

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

# Use a constant array instead of separate constants
use constant SERVERNAMES => qw(//firstserver/somedir/
                            //secondserver/somedir/
                            //thirdserver/somedir/);
                            
foreach my $srvr (SERVERNAMES) {
    print "$srvr \n";
}
d5e5 109 Master Poster

I want to calculate somebody date using his/her Date of Birth which is located on the database column name(DOB)..which sql function do i use and how do i use it on the Sqlquery..please help

To write a query that shows somebody's date of birth you don't need a function. Assuming that DOB is defined as a DATE datatype you can select it using the default format, which is YYYY-MM-DD.

mysql> select * from people where name = 'somebody';
+----+----------+------------+
| id | name     | dob        |
+----+----------+------------+
|  2 | somebody | 1974-04-18 | 
+----+----------+------------+
1 row in set (0.00 sec)
d5e5 109 Master Poster

Thanks for the help, it is working.
So, basicly i can use this type of code to any field that required only digit, isn't it?

That's right. If you know the exact number of digits required is 4, for example, you can use /^\d{4}$/ . If you want a length of between 3 and 8 consecutive digits you can say /^\d{3, 8}$/ . If you want at least one or more digits (no maximum) you can use /^\d+$/ .

d5e5 109 Master Poster

/^\d{16}$/ Many variations are possible.

Yes, I like that one better than the one I posted. Presumably all VISA credit card numbers have the same length, so you can enforce both the length and all-digit requirement with one regex. You can do the same for 'year', 'month', etc. If you need to eliminate leading or trailing spaces, you can strip them from the string before matching, to keep the regex simple.

d5e5 109 Master Poster

Try adding the following to the validate function.

var ccnum = document.getElementById("credit card number").value;
        var alldig = false;
        alldig = /^\s*\d+\s*$/.test(ccnum); //Consecutive digits, optional leading or trailing spaces        
	if (alldig == false)
	{
		alert("Credit Card Number must consist of numbers only");
		return false;
	}
d5e5 109 Master Poster

os.popen returns an object that you can assign to a variable and iterate through. I read about it at http://linux.byexamples.com/archives/366/python-how-to-run-a-command-line-within-python/

>>> import os
>>> f=os.popen("ls -la")
>>> for i in f.readlines():
	print "myresult:", i,

	
myresult: total 9804
myresult: drwxr-xr-x 55 david david    4096 2010-05-04 16:28 .
myresult: drwxr-xr-x  3 root  root     4096 2010-02-25 16:05 ..
myresult: drwx------  3 david david    4096 2010-02-26 14:37 .adobe
myresult: -rw-------  1 david david    9596 2010-05-03 11:38 .bash_history
etc......................
d5e5 109 Master Poster
#!/usr/bin/env python
import re
DataDir = '/home/david/Programming/Python'
phonefile = DataDir + '/' + 'PhoneNumbers.txt'

"""Read each line from file. If it starts with
a string of exactly 10 consecutive digits, assume
this is a phone number and print it."""

ph_nbr_pattern =  r'^(\d{10})(?:\s|$)'
compile_obj = re.compile(ph_nbr_pattern)

file2read = open(phonefile, 'r')
for currentline in file2read:
    match_obj = compile_obj.search(currentline)
    if match_obj:
        print currentline.rstrip()
    
file2read.close()
"""Output is:
4616186224
3501292628
2698109000
4398248508
8462632398
5414846117
9167449701
5097458418
"""
d5e5 109 Master Poster

Why not do it as follows? my ($oct1, $oct2, $oct3, $oct4) = ($1, $2, $3, $4); After all, you wrote the regular expression, so you know it returns four matched groups. The sites you googled may be addressing the situation where programmers don't know how many data items they may need to save and so are thinking of creating variable names dynamically at runtime. In those situations, you can use hashes instead of scalar variables. Here is a quote from Beginning Perl which may be saying something similar to what you've been reading about using hashes instead of creating variables on-the-fly.

d5e5 109 Master Poster

Yes sir, the example that I stated was a one-to-many relationship, but how are you going to verify if the connection made from both table is really a one-to-many relationship?

There is nothing to verify. Your table definitions logically entail that the relationship is one customer to many orders, where 'many' means zero or more. The foreign key in the order table references the primary key of the customer table, which is unique by definition. Therefore there can exist no more than one customer record associated with any order record. No column in the customer table points to an order, so there is no constraint on how many orders can belong to this customer. How could this NOT be a one-to-many relationship?

d5e5 109 Master Poster

Thanks tonyjv for the clarification and the test data.

#!/usr/bin/env python
import re
def FindName(name,list1):
    """ searches for a pattern in the list, returns the complete list entry(s)
    as a string. Is case sensitive.
    """
    mlist = []
    pattern = r"""^(%s.*)$""" % (name)
    for item in list1:
        match = re.search(pattern, item)
        if match:
            mlist.append(match.group())
        
    if len(mlist) > 0:
        return ', '.join(mlist)
    else:
        return 'Fail ' + name

            
china=['In', 'China', 'people', 'teach',"Confusius's",
       'teachings','dilligently.','Those',"Confusius''s",
       'teachings','are','called','Taoism.']

this='Conf'

print FindName(this,china)

print [(i,x) for (i,x) in enumerate(china) if x.startswith(this)]

"""Output:
Confusius's, Confusius''s
[(4, "Confusius's"), (8, "Confusius''s")]
"""
d5e5 109 Master Poster

if ($record =~ m/BUNP:\s*(.*)$/) { #Allow optional space, then capture to end of line

d5e5 109 Master Poster

ok,thank you for help!

I think that constructor is missing,and that should be fixed.

I use firebug for debuging.

You're welcome. I can see it's still not working. As you say, it may need some kind of constructor method. I haven't learned enough about objects yet. Good luck.:)

d5e5 109 Master Poster
#`cat $Header_File $Detail_File $Trailer_File > $CH_Report`;
#Instead of the above `cat ... etc. do the following
open OUT, '>', $CH_Report or die "Cannot open $CH_Report $!";

open IN, '<', $Header_File or die "Cannot open $Header_File $!";

while (<IN>) {
   print OUT $_;
}
print OUT "\n"; #Newline between header and detail
close IN;

open IN, '<', $Detail_File or die "Cannot open $Detail_File $!";

while (<IN>) {
   print OUT $_;
}
print OUT "\n"; #Newline between detail and trailer
close IN;

open IN, '<', $Trailer_File or die "Cannot open $Trailer_File $!";

while (<IN>) {
   print OUT $_;
}
close IN;
close OUT;
d5e5 109 Master Poster

var nazivLinka = document.getElementById("prvo").value; is invalid. Remove the '.value' from the end. Do the same to var url = document.getElementById("drugo").value; But it still may not work if there are other errors. You need some kind of javascript error console in your browser to point you to what causes the code to break. I use Firefox version 3.5.9 which has an error console so you can know more than just 'it didn't work'.

Also look at <table id="tabela" style="background-color:yellow; length:100%; width:100%;"> Firefox doesn't accept 'length' as a table attribute.

d5e5 109 Master Poster

I saw the link in bottom now,so javascript onload code if written in head wont work?

I don't know. I haven't worked with scripts in web pages for quite a while but I remember that we usually (maybe always?) had to define our functions in the head section and not the body to make them work when called.

But a script that does things like

<script type="text/JavaScript">
<!--
document.write("Hello World!")
//-->
</script>

would more likely go in the body section, depending where on the page you wanted it to write.

d5e5 109 Master Poster

If you use findall instead of search you get a list of strings.

>>> import re
>>> MyStr = "<test>some text here</test> <other> more text </other> <test> even more text</test>"
>>> m=re.compile('<test>(.*?)</test>', re.DOTALL).findall(MyStr)
>>> print m
['some text here', ' even more text']
>>>

Sounds like that will definitely help down the road, but it still didn't work in this case:

>>> import re
>>> MyStr = "<test>some text here</test> <other> more text </other> <test> even more text</test>"
>>> m=re.compile('<test>(.*?)</test>', re.DOTALL).search(MyStr)
>>> print m.group(1)
some text here
>>> print m.group(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: no such group

Dave

d5e5 109 Master Poster
<html>
<head>
<title>moje vezbanje</title>
<script type="text/JavaScript">
<!--
/*
Delete the test() function from between the <body> tags
and place it here between the <head> tags
*/
function test()	{
	alert('123123');	
	}
//-->
</script>

</head>

<body onload="alert('sdfsfd')">
<script type="text/javascript">
//alert("jhgfgh");
function klasa()	{


var nazivLinka = document.getElementById("prvo").value;
var url = document.getElementById("drugo").value;

//alert(nazivLinka);

//druga.createNode(input type="text" value="pocetni text");


function dodajLink()	{
	
	var link = document.createNode("a");//1 kreir element
	
	link.innerHTML = nazivLinka;//2 dodaj atribute
	link.href = url;
	document.getElementById("prva_kol").appendChild(link);//3 dodaj element na stranu

	}
	

function pozicija(id1,x,y)  {
id1.

}	
*/
}
</script>

<script>
var a = new klasa();
</script>

<table id="tabela" style="background-color:yellow; length:100%; width:100%;">
	<tr>		
		<td id="prva_kol" style="background-color:magenta; width:300px; height:300px;">11

		</td>
		<td id="druga_kol" style="background-color:red;">
		<input type="text" id="prvo" value="naziv linka"/>
		<input type="text" id="drugo" value="http://"/>
		<input type="button" onclick="test();" value="dugme"/>
		
		</td>
		<td style="background-color:blue;">33</td>	
	</tr>		
</table>


</body>
</html>

See this link for more information about where to place the scripts.

d5e5 109 Master Poster

When you compare alphanumeric values with the numeric comparison operator you get true when you don't expect it. Change

while ($exp =="y") {

to

while ($exp eq "y") {

Binary "==" returns true if the left argument is numerically equal to the right argument.
Binary "eq" returns true if the left argument is stringwise equal to the right argument. (from perldoc perlop)

d5e5 109 Master Poster

I can't point to an authority to back me up, but my guess is that we discover the one-one vs. on-many relationship by studying the PRIMARY key of the tables in question. Because the values of the primary keys of the two tables do not have to be identical between linked records of the two tables the relationship is one-many. The table with the foreign key is on the many side of the relationship.

What if you wanted a one to one relationship between two tables? For example, a customer table and a Customer_Current_Address table. It seems to me that they both would have the same PRIMARY key to support the one to one relationship. Plus one of the tables would have a foreign key to preserve referential integrity. In other words, the rule that you can't insert a Customer_Current_Address record before inserting a customer record is expressed by having a foreign key field in the Customer_Current_Address table.

Hi, not very familiar with mysql. I have here a mysql statement:

table customer:

CREATE TABLE Customer
(SID integer,
Last_Name varchar(30),
First_Name varchar(30),
PRIMARY KEY (SID));

table orders:

CREATE TABLE ORDERS
(Order_ID integer,
Order_Date date,
Customer_SID integer,
Amount double,
Primary Key (Order_ID),
Foreign Key (Customer_SID) references CUSTOMER(SID));

My question is, how are you going to identify if the referencing is a one-to-many or a one-to-one relationship??

d5e5 109 Master Poster

Not sure if you intended to allow a space between the colon and $v or not. Assuming not, the following should work.

#!/usr/bin/perl
#Regex.pl
use 5.006;
use strict;
use warnings;

#Assign some values to variables and build request string
my $k = 'kryptonite';
my $v = 'valium';
my $valid = 1;
my $request = "RemoveAcc $k:$v";# <----No space allowed between : and $v, right?
print "request is $request\n";
if ($valid and ($request =~ m/RemoveAcc\s*(\w+):(\w+)/)){
	my $first = $1;
	my $second = $2;
	print "First value is $first\nSecond value is $second\n";
} else {
	print "Not valid or doesn't match\n";
}
samready commented: thanks that did it. (you're right, the space wasn't supposed to be there, but i put it there so it didn't make a smiley :$" +0
d5e5 109 Master Poster

Hi
i want to install this cpan
CPAN-1.9402.tar.gz
Crypt-Rijndael-1.09.tar.gz

the prblem is t install it from /tmp and not networking

Thanks
Danny

In the book Beginning Perl look in Chapter 10. There's an example of installing from a downloaded archive. Chapter 10 is available online from here so just search for "Installing a Module Manually" and follow his example.

d5e5 109 Master Poster

This worked OK for me after commenting out a couple of print statements that were trying to send output to the web page before printing the html header.

#!/usr/bin/perl
use strict;
use warnings;
use POSIX qw(strftime);
my $output;
my $cur_time = strftime "%a %b %e %H:%M:%S %Y", localtime;
#print "$cur_time\n"; #Don't print to webpage before printing your header

open PS, "/bin/netstat -nra 2>&1|" or die "failed with : $1";
while(<PS>)
{
	#print;
	$output .=$_;
}
#print $output; #Don't print to webpage before printing your header
close (PS);

#The first print statement must contain your header info plus two newline characters (\n\n)
print "Content-type: text/html\n\n"; #This has to contain the first lines you send to your web page
print "<HTML>\n";
print "<HEAD>\n<TITLE>Netstat Sample </TITLE>\n</HEAD>\n"; 
print "<strong>";
print "<br>Curent time is <font color=\"#FF0000\">$cur_time</font> MST";
print "</br>";
print "<br>$output</br>";
print "</strong>";
print "</body>\n</html>";
d5e5 109 Master Poster

Hello,

I'm new to perl, how do I modify your code to find third level folder under a given Base_Dir?

Thanks

There are more than one scripts in this topic that could be modified to do what you want, but some would take a lot more work than others.

If I needed to find the third level folder under a given Base_Dir for myself or my boss at work, I would prefer to do it in two steps:

  1. use File::Find module as in the examples above, but only to print ALL subdirectories
  2. Write a second Perl script that reads the list of subdirs from Step 1 and decides which ones have the desired level of depth

By breaking it into two steps you get to examine the output from Step 1 and first manually pick out the lines you want your second script to find, and then write and test your second script until you are satisfied it finds exactly what you want from the data produced by your first script. When you want to use your two scripts together you can run them both from the command line with a piping symbol between them to direct the output (STDOUT) of the first script into the input (STDIN) of the second.

d5e5 109 Master Poster

Hi

Im trying to pull out a list of meetings, and the associated number of comments attached to each meeting. Comments are assigned a category (ie meetings) and a linkid (the uniqe id of the meeting) - Im using this query, buts its cutting out all meetings that don't have any comments attached, and Ive hit a mental block... how do I pull out all meetings (and a value of zero if there are no comments?!)

$sql = "SELECT m.id,m.title, m.blurb, m.mktime, m.start, m.stop, u.name AS first, u.surname, v.name AS venue, COUNT(c.id) as comment_count FROM meetings AS m 
LEFT JOIN users As u ON u.id = m.userid 
LEFT JOIN venues AS v ON v.id = m.venueid 
LEFT JOIN comments AS c ON c.linkid = m.id 
WHERE c.category = 'meetings' 
ORDER BY m.mktime ASC";

To pull out all meetings including those with no comments you need to consider that sometimes the values in the result set from the comments table will be null (for those meetings that have no corresponding rows in the comments table.) Try altering your WHERE clause as follows: WHERE c.category = 'meetings' OR c.category IS NULL

d5e5 109 Master Poster

I don't know about SQL loader but have you tried the usual way of assigning the result of Perl commands? For example if I wanted to show the result of executing the print command I would do this:

my $result = print "hello world\n";
print $result;

which shows that the print command returns a value of 1 when it prints successfully.

As I say, I don't have MySQL or SQL loader installed yet so I may be misunderstanding your question.

d5e5 109 Master Poster

Thank you!! That worked perfectly.

What if you were not hard coding the push of a value into an array for a given key... Do you know how you would loop through a hash to keep searching for a different value for the same key if the key is already defined with a given value?

I have a table with multiple values per key for some entries, but they are all in distinct rows and am stumped at how to make my search keep searching if a key/value pair is already defined...

Sorry to pester, but I appreciate your help!

As long as you don't need to preserve the order in which these multiple values are saved, it seems to me that a hash within a hash would serve you better than an array within a hash because hash keys are always unique. You wouldn't need to check if a key already exists before adding it, because there is no value paired with it so adding the key more than once just overwrites the key with no loss of information.

#!/usr/bin/perl
#HashOfHashes.pl
use 5.006;
use strict;
use warnings;
my $key = 'B-flat';
my $systemKey = 'F-sharp';
my $referenceTable;
# @values_to_store contains values to save in the hash for B-flat.
# Note that the element 'Another key' will be added to the hash twice.
# THIS SHOULDN'T MATTER because the duplicate key will overwrite itself.
my @values_to_store = ($systemKey, 'Another key', 'Key Largo Florida', 'Another key');

foreach (@values_to_store) {
   undef …
d5e5 109 Master Poster

You can always use an array reference, in curly braces, in place of the name of an array. For example, "@{$aref}" instead of @array. (from perlreftut)

Declare $v as a scalar variable to contain a reference to an array where you can store multiple values.

#!/usr/bin/perl
#HashofArrays.pl
use 5.006;
use strict;
use warnings;
my $key = 'B-flat';
my $systemKey = 'F-sharp';
my %referenceTable;

push @{$referenceTable{$key}},  $systemKey;
push @{$referenceTable{$key}},  'Another key';
push @{$referenceTable{$key}},  'Key Largo Florida';

my ($k, $v); #Not @v -- $v will contain string that will be a reference to an array

while (($k, $v) = each(%referenceTable)){
     print "Hash key is $k \n";
     print "Values stored in the dereferenced array are: \n ";
     foreach (@{$v}) { #Using an array reference as an array see perlreftut
        print "$_\n";
     }
}
d5e5 109 Master Poster
#!/usr/bin/perl
#ElementsIn3Arrays.pl
use 5.006;
use strict;
use warnings;

my @a1 = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
my @a2 = (1, 2, 3, 4, 6, 8, 10, 12, 14);
my @a3 = (1, 2, 3, 5, 7, 9, 11, 13, 15);
my %h = (); #Empty hash
my $item;
# Fill hash with unique keys from all 3 arrays
# and add references to hashes with keys Array 1 .. 3 
# and value 1 (indicating 'true') when item is in that array
foreach $item (@a1) {$h{$item}->{'Array 1'} = 1};
foreach $item (@a2) {$h{$item}->{'Array 2'} = 1};
foreach $item (@a3) {$h{$item}->{'Array 3'} = 1};
printf("%4s%15s%15s%15s\n", "Elem", "Array 1", "Array 2", "Array 3");

foreach $item (sort {$a<=>$b} (keys (%h))) {
	printf "%4s%15s%15s%15s\n", $item, 
	 ($h{$item}->{'Array 1'}) ? "Yes" : "",
	 ($h{$item}->{'Array 2'}) ? "Yes" : "",
	 ($h{$item}->{'Array 3'}) ? "Yes" : "";
}
d5e5 109 Master Poster
#!/usr/bin/perl
#ElementsIn3Arrays.pl
use 5.006;
use strict;
use warnings;

my @a1 = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
my @a2 = (1, 2, 3, 4, 6, 8, 10, 12, 14);
my @a3 = (1, 2, 3, 5, 7, 9, 11, 13, 15);
my %h = ();
my $item;

foreach $item (@a1, @a2, @a3) {$h{$item}++}; #Build hash of unique values
printf("%4s%20s%20s%20s\n", "Elem", "Array1", "Array2", "Array3");
foreach $item (sort {$a<=>$b} (keys (%h))) {
	printf "%4s%20s%20s%20s\n", $item, is_in($item, \@a1), is_in($item, \@a2), is_in($item, \@a3);
}

sub is_in {
	my ($element, $array_ref) = @_;
	my @array = @{$array_ref};
	if (grep {$_ eq $element} @array) {
		return 'Yes'; #Found it
	}
return ''; #Didn't find it
}
d5e5 109 Master Poster

It depends what you mean by difference. Your question (but not the Perl script you showed us) implies that by 'difference' you mean the difference between the size of the array having the most elements minus the size of the array having the least elements. If that is what you mean then mitchems script will give you your answer.

But the Perl script you showed us implied that you were looking for some other kind of difference, i.e the size of the list of elements that were in either @a or in @b but not in both. That would not necessarily equal the difference in size of the two arrays, as your question implies.

d5e5 109 Master Poster

However, If anyone knows the best way to print out just the next 2-3 lines and, more importantly, the previous 2-3 lines I'd appreciate the advice.

EDIT: After consideration, I'm guessing it would be easiest to keep the last 2-3 lines in an array and push-shift the array each for each loop through the while statement.

Jonathan Leffler posted a Perl script he calls 'sgrep', on Stackoverflow which takes a similar approach to what you are thinking of, except he doesn't look at two lines together so maybe it won't work for you. But you may want to look at it for inspiration.

I would try to do something like the following instead:

#!/usr/bin/perl
#PrintMatchContext01.pl
use 5.006;
use strict;
use warnings;
use Tie::File;
sub max ($$) { $_[$_[0] < $_[1]] }
sub min ($$) { $_[$_[0] > $_[1]] }
my $file_in = 'data.txt';
my @lines;
tie @lines, 'Tie::File', $file_in or die "Unable to tie $file_in $!";
my $n_recs = @lines; # how many records are in the file?
my @lnbrs = ();
my $i = 0;
while ($i < $n_recs - 1) {
    my $twolines = $lines[$i] . $lines[$i + 1];
    if ($twolines =~ m/file\s+for\s+(?:bankrup|chapter)/im) {
        push @lnbrs, $i
    }
    $i++;
}

foreach my $ln (@lnbrs) {
    my $start = max($ln-3, 0);
    my $end = min ($ln+3, $n_recs);
    print '-' x 75, "\n";
    foreach ($start .. $end) {
        print "$lines[$_]\n";
    }
}
untie @lines;
d5e5 109 Master Poster

$brcount++ while $data =~ /(file for bankrup)|(file for chapter)/gi; This assumes that those two phrases will never span across two lines. Is that correct? If so, then you don't need to consider appending two lines together to do each match.

d5e5 109 Master Poster

I can't give you an example file as I myself am not provided with one. All I've been told is that the script should be able to find ANY date or time in ANY format used by english speaking people. This could be dd/mm/yy or mm/dd/yy or 1st Jan 2010 or Jan 1st 2010 etc. and for time it can be 12 or 24 hour time. Dodgy dates are acceptable, like 29/02/2010 (2010 not a leap year) or 31/4/2010 (April only has 30 days).

I hope whoever asked you for this will pay you by the hour, because they have given you a lot of work, Here is a simplified example of a script that matches only two date formats. It expects at least one filename following the program name when you run it on the command line. For example: perl FindDates.pl Dates_1.txt

#!/usr/bin/perl
#FindDates.pl
use 5.006;
use strict;
use warnings;

my $d1 = qr{(?:0[1-9]|1[012])[- /.](?:0[1-9]|[12][0-9]|3[01])[- /.](?:19|20)\d\d}; #Matches mm/dd/yyyy
my $d2 = qr{(?:0[1-9]|[12][0-9]|3[01])[- /.](?:0[1-9]|1[012])[- /.](?:19|20)\d\d}; #Matches dd/mm/yyyy
my @dates;

while (<>){
	my @d = m/$d1 | $d2/gx;
	push @dates, @d if scalar(@d);
}

print "$_ \n" foreach @dates;

The file 'Date_1.txt which I used for testing contains the following data:

Let's go somewhere on 04/23/2010 or 23/04/2010 as the British would say.
This would be so much easier if we could assume all the dates would
be at the start or the end of each line.
12/25/2009 Like that.
Or if we could assume that every date …
d5e5 109 Master Poster

How you write the Perl script depends on what assumptions, if any, you can make about the input files. If they are generated by another computer program, such as one making an activity log or list of transactions, then there should be a finite number of possible ways the dates and times can be formatted and where they will occur in each line. If, however, they are a collection of documents or web pages from a variety of sources composed in free-form text then you will have to write a fairly complex script with many regex patterns to distinguish the dates and times from everything else.

You can read about creating regex patterns to match a valid date at http://www.regular-expressions.info/dates.html

There are many modules freely available on CPAN that do some kind of parsing of dates and/or times. I have no experience with parsing dates in Perl and so I don't know if any of these modules will do what you want.