Re-reading your question, I think your problem might be a little different than I thought at first. The problem you are running into is that the escaped line ending is ruining your day because you are reading line by line through the file.
There are a couple ways to handle that. One is to check if the line ends with a backwhack and a newline and then to remove those characters and append the next line before continuing your processing. Another is to read the whole file into a single variable and remove the escaped line endings all at once with something like $file =~ s/\\\n//gs;.
Any way you do it is going to require caution though. Unless you are prepared to build a real parser for your input, you might run into problems.
-sauoq
"My two cents aren't worth a dime.";
| [reply] [d/l] |
If I understand your question, you just need to escape your backwhack (with another backwhack.)
$s = 'There is a \ random backwhack in this sentence.';
print "I found it\n" if $s =~ /\\/;
-sauoq
"My two cents aren't worth a dime.";
| [reply] [d/l] |
Welcome to the Monastery. For being your first post, it's better than what other people have done as their first posts (or even the fourth or fifth, for some people).
Showing us a little bit of your input data is good (and putting that data sample inside "<code>" tags is very good).
Showing us the code you've tried would be even better (especially if you put that inside "<code>" tags also).
For example, it could be that you've only read the first line of input (which happens to end with a backslash). Are you sure you are reading the following lines as well?
| [reply] |
Here is the data and code:-
create_clock -name ldtclock -period 60
create_clock -name mxuclock -period 20
set_input_clock 50 -rise -clock "ldtclock" \
find(port,"mxi_port")
set_input_clock 40 -fall -clock "mxuclock"\
find(port,"mxu_port")
so if set_input_clock is 40 but the clock is 20 so I have to make it 0.
while(<file>)
{
if (/create_clock\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)*/ ) {
$CLK1{$2}= $4;
print clk_file ;
elsif (/set_input_clock\s+(\d+)\s+(\S+)\s+(\S+)\s+\"(\w+)\"\s+(\S+)*/
+)
{
$d =$1;
$c =$4;
if ($delay < 0) {
print clk_file "set_input_clock 0 $2 $3 $4 $5 \n";
next;
}
if (exists $CLK{$c})
{
if ($CLK{$c}*0.95 < $d)
{
printf clk_file "set_input_clock %.6f $2 $3 $4 $5 \n",$C
+LK{$c}*0.5;
}
else{print clk_file;}
}
| [reply] [d/l] [select] |
Yes you are absolutely right, I am reading it line by line. How do I append the line, I am able to identify \ and \n.
Thanks | [reply] |
while ($line = <>) {
while ($line =~ s/\\\n//) {
$line .= <>;
}
# ... do useful stuff with $line here ...
}
The outside loop reads a line. The inside loop 1) checks to see if it ends with backwhack-newline, 2) lops off the backwhack-newline, 3) appends the next line from the file, and 4) repeats.
Note that steps 1 and 2 are both done in the while's conditional with the substitution. (If the substitution is successful, then the line did end with backwhack-newline and it was removed.)
Caveats include the assumption that a newline is your command terminator and the backwhack escapes it by immediately preceding it (as if with a shell script, for instance) and also that you won't have to worry about other escaped characters. An example of the latter might be a line that ends with "\\\n", which will break this code if that should be interpreted as an escaped backwhack rather than an escaped newline.
-sauoq
"My two cents aren't worth a dime.";
| [reply] [d/l] [select] |
Please note that "There is a \" is in one line and
"random backwhack in this sentence." starts in a new line so there is a hidden \n.
so if the command line is
set_input_clock 50 -rise -clock "ldtclock" \
find(port,"mxi_port")
Then I am doing this...
elsif (/set_input_clock\s+(\d+)\s+(\S+)\s+(\S+)\s+\"(\w+)\"\s+(\S+)*/ )
{
print STDERR "set_input_clock $1 $2 $3 $4 $5 \n";
but I also need to read the port name.
Presently I can only print
set_input_clock 50 -rise -clock "ldtclock" \
Is there a way?
Thanks | [reply] |
Note that you can re-edit the text of anything you post here to update it. For example, you can still add "<code>" and "</code>" around the snippet of perl code in the node that I'm replying to here. (And people like to be told when a node has been updated, so include a little extra comment to say you added code tags.)
So, if the data you need to put together is coming in on multiple lines, there are a few different ways to deal with this, and the method you'll like best will depend on other factors, like: how much other data is there in the input file? how much of that other data are you using? do you need to pull lots of occurrences of the target info from this one file? do you have a lot of files you need to process this way? do the patterns of information vary from one instance to the next? ... and so on.
For a start, let's suppose the input consistently has this sort of layout:
set_input_clock \d+ -someParam -otherParam "paramValue" \
find(string,"quoted_string")
That's two lines of data, and you want the digit string, the params and param value, and the quoted string from the next line.
One way would be (updated, based on a more detailed sample of data you list later in this thread):
my $record = '';
while (<>) { # read a line of input data
s/\s+$/ /; # normalize all line-final whitespace to " "
$record .= $_;
if ( /\\ $/ ) { # if line ended with a backslash
$record =~ s/\s*\\ / /; # remove it from the record,
next; # and move on to add next line
}
# if ( $record !~ /find/ ) { # if record doesn't have this
# next; # try adding next line
# }
# now just figure out what to do with $record -- e.g.
my @tokens = split ' ', $record;
$record = ''; # in case there's another record coming
print "\n", join( ' ', @tokens ), "\n";
# just guessing here, about what might be useful...
my %params = ();
$params{cmd} = shift @tokens;
$params{amount} = shift @tokens if ( $params{cmd} =~ /set/ );
my $lastparam;
while ( @tokens ) {
$_ = shift @tokens;
if ( /^-/ ) {
$params{$_} = '';
$lastparam = $_;
}
elsif ( /find\W+port\W+(\w+)/ ) {
$params{port} = $1;
last;
}
else {
$params{$lastparam} = $_;
}
}
for ( sort keys %params ) {
print "$_ => $params{$_}\n";
}
print "\n";
}
Another update: looking again at your later reply, about how you need to keep track of clocks that are created and what their various parameters are, I think you'll be able to see how to maintain your overall "%clocks" hash in a manner similar to how I create the "%params" hash for each record in the code above. | [reply] [d/l] [select] |
Thanks a lot guys, you all have been great :-) | [reply] |