I want to substitute all " in the string $input with /" and I come up with the following code:
#!/usr/bin/perl -w
use CGI;
use CGI::Carp qw ( warningsToBrowser fatalsToBrowser );
my $q = CGI -> new;
print $q -> header();
$input = 'abc"abc';
(my $output = $input) =~ s/"/"/g;
print "input = $input\n";
print "output = $output\n";
However, the $output is not changed. How can I get this right?
You should use a module suitable for the purpose, such as HTML::Entities:
use strict;
use warnings;
use HTML::Entities;
my $input = 'abc"abc';
print encode_entities($input);
Output:
abc"abc
In your code, the variable $input is not changed because you are using parentheses to avoid it.
(my $output = $input) =~ s/"/"/g;
This will enforce the assignment to happen first, overruling precedence. Then the regex substitution is applied to $output. When I run your code, I get the expected output:
input = abc"abc
output = abc"abc
If you do not get this output, I expect the quotes in your string is something different than you think.
Related
I am new to perl.
Inside my input file is :
james1
84012345
aaron5
2332111 42332
2345112 18238
wayne[2]
3505554
Question: I am not sure what is the correct way to get the input and set the name as key and number as values. example "james" is key and "84012345" is the value.
This is my code:
#!/usr/bin/perl -w
use strict;
use warnings;
use Data::Dumper;
my $input= $ARGV[0];
my %hash;
open my $data , '<', $input or die " cannot open file : $_\n";
my #names = split ' ', $data;
my #values = split ' ', $data;
#hash{#names} = #values;
print Dumper \%hash;
I'mma go over your code real quick:
#!/usr/bin/perl -w
-w is not recommended. You should use warnings; instead (which you're already doing, so just remove -w).
use strict;
use warnings;
Very good.
use Data::Dumper;
my $input= $ARGV[0];
OK.
my %hash;
Don't declare variables before you need them. Declare them in the smallest scope possible, usually right before their first use.
open my $data , '<', $input or die " cannot open file : $_\n";
You have a spurious space at the beginning of your error message and $_ is unset at this point. You should include $input (the name of the file that failed to open) and $! (the error reason) instead.
my #names = split ' ', $data;
my #values = split ' ', $data;
Well, this doesn't make sense. $data is a filehandle, not a string. Even if it were a string, this code would assign the same list to both #names and #values.
#hash{#names} = #values;
print Dumper \%hash;
My version (untested):
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
#ARGV == 1
or die "Usage: $0 FILE\n";
my $file = $ARGV[0];
my %hash;
{
open my $fh, '<', $file or die "$0: can't open $file: $!\n";
local $/ = '';
while (my $paragraph = readline $fh) {
my #words = split ' ', $paragraph;
my $key = shift #words;
$hash{$key} = \#words;
}
}
print Dumper \%hash;
The idea is to set $/ (the input record separator) to "" for the duration of the input loop, which makes readline return whole paragraphs, not lines.
The first (whitespace separated) word of each paragraph is taken to be the key; the remaining words are the values.
You have opened a file with open() and attached the file handle to $data. The regular way of reading data from a file is to loop over each line, like so:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
my $input = $ARGV[0];
my %hash;
open my $data , '<', $input or die " cannot open file : $_\n";
while (my $line = <$data>) {
chomp $line; # Removes extra newlines (\n)
if ($line) { # Checks if line is empty
my ($key, $value) = split ' ', $line;
$hash{$key} = $value;
}
}
print Dumper \%hash;
OK, +1 for using strict and warnings.
First Take a look at the $/ variable for controlling how a file is broken into records when it's read in.
$data is a file handle you need to extract the data from the file, if it's not to big you can load it all into an array, if it's a large file you can loop over each record at a time. See the <> operator in perlop
Looking at you code it appears that you want to end up with the following data structure from your input file
%hash(
james1 =>[
84012345
],
aaron5 => [
2332111,
42332,
2345112,
18238
]
'wayne[2]' => [
3505554,
]
)
See perldsc on how to do that.
All the documentation can be read using the perldoc command which comes with Perl. Running perldoc on its own will give you some tips on how to use it and running perldoc perldoc will give you possibly far more info than you need at the moment.
I'm in the process of learning Perl and am trying to write a script that takes a pattern and list of files as command line arguments and passes them to a subroutine, the subroutine then opens each file and prints the lines that match the pattern. The code below works; however, it stops after printing the lines from the first file and doesn't even touch the second file. What am I missing here?
#!/usr/bin/perl
use strict;
use warnings;
sub grep_file
{
my $pattern = shift;
my #files = shift;
foreach my $doc (#files)
{
open FILE, $doc;
while (my $line = <FILE>)
{
if ($line =~ m/$pattern/)
{
print $line;
}
}
}
grep_file #ARGV;
Shift pops an element from your parameter (see: http://perldoc.perl.org/functions/shift.html).
So #files can only contain one value.
Try
sub foo
{
my $one = shift #_;
my #files = #_;
print $one."\n";
print #files;
}
foo(#ARGV);
There is little reason to use a subroutine here. You are just putting the whole program inside a function and then calling it.
The empty <> operator will read from all the files in #ARGV in sequence, without you having to open them explicitly.
I would code your program like this
use strict;
use warnings;
my $pattern = shift;
$pattern = qr/$pattern/; # Compile the regex
while (<>) {
print if $_ =~ $pattern;
}
I'm new to Perl and i'm trying to extract the path of a file. Please help me with a suitable regular expression, this is my code:
$string = "D:/EZ-VPN/NKEMSL0-V02.txt------vpnclient server 156.37.253.97";
I want to extract "D:/EZ-VPN/NKEMSL0-V02.txt" and "156.37.253.97" and store it in 2 scalar variables. Please suggest a regular expression to extract these.
thanks in advance
#!/usr/bin/perl
use strict;
my $string = "D:/EZ-VPN/NKEMSL0-V02.txt------vpnclient server 156.37.253.97";
$string =~ m/(.*?)--+.* (\d+\.\d+\.\d+\.\d+)/;
print $1."\n";
print $2."\n";
This should work for you.
Perl gathers the results from the regex's brackes (so called capture groups) in the $1, $2 ... $n variables.
The filename is in $1, the IP adress is in $2.
Using the string of 6 consecutive dashes to mark the end of the path:
my($path, $ipaddress) = ($string =~ m/(.*?)------.* (\d+\.\d+\.\d+\.\d+)/);
Test script:
#!/usr/bin/env perl
use strict;
use warnings;
my $string = "D:/EZ-VPN/NKEMSL0-V02.txt------vpnclient server 156.37.253.97";
my($path, $ipaddress) = ($string =~ m/(.*?)------.* (\d+\.\d+\.\d+\.\d+)/);
print "path = $path; IP = $ipaddress\n";
Output:
path = D:/EZ-VPN/NKEMSL0-V02.txt; IP = 156.37.253.97
my ($x, $y) = split /------/, $string;
my ($z) = $y =~ /(\S+)\z/;
The file does not have spaces and do i need to keep every word in the corresponding array,
content in var, the file is more large, but this is ok.
my $file = "http://www.ausa.com.ar/autopista/carteleria/plano/mime.txt";
&VPM4362=008000&VPM4381=FFFFFF&VPM4372=FFFFFF&VPM4391=008000&VPM4382=FFFF00&VPM4392=FF0000&VPM4182=FFFFFF&VPM4181=FFFF00&VPM4402=FFFFFF&VPM4401=FFFF00&VPM4412=008000&VPM4411=FF0000&VPM4422=FFFFFF&VPM4421=FFFFFF&VPM4322=FFFF00&CPMV001_1_Ico=112&CPMV001_1_1=AHORRE 15%&CPMV001_1_2=ADHIERASE AUPASS&CPMV001_1_3=AUPASS.COM.AR&CPMV002_1_Ico=0&CPMV002_1_1=ATENCION&CPMV002_1_2=RADARES&CPMV002_1_3=OPERANDO&CPMV003_1_Ico=0&CPMV003_1_1=ATENCION&CPMV003_1_2=RADARES&CPMV003_1_3=OPERANDO&CPMV004_1_Ico=255&CPMV004_1_1= &CPMV004_1_2=&CPMV004_1_3=&CPMV05 _1_Ico=0&CPMV05 _1_1=ATENCION&CPMV05 _1_2=RADARES&CPMV05 _1_3=OPERANDO&CPMV006_1_Ico=0&CPMV006_1_1=ATENCION&CPMV006_1_2=RADARES&CPMV006_1_3=OPERANDO&CPMV007_1_Ico=0&CPMV007_1_1=ATENCION&CPMV007_1_2=RADARES&CPMV007_1_3=OPERANDO&CPMV08 _1_Ico=0&CPMV08 _1_1=ATENCION&CPMV08
the code.
#!/bash/perl .T
use strict;
use warnings;
use LWP::Simple;
my $file = "http://www.ausa.com.ar/autopista/carteleria/plano/mime.txt";
my $mime = get($file);
my #new;
foreach my $line ($mime) {
$line =~ s/&/ /g;
push(#new, $line);
}
print "$new[0]\n";
Try this way but when I start the array is equal to (all together)
the output I need
print "$new[1]\n";
VPM4381=FFFFFF
You don't want to substitute on &, you want to split on &.
#new = split /&/, $line;
What is the right way to stop an endless while-loop with a Term::Readline::readline?
This way I can not read in a single 0
#!/usr/bin/env perl
use warnings;
use strict;
use 5.010;
use Term::ReadLine;
my $term = Term::ReadLine->new( 'Text' );
my $content;
while ( 1 ) {
my $con = $term->readline( 'input: ' );
last if not $con;
$content .= "$con\n";
}
say $content;
and with
last if not defined $con;
the loop does never end.
You can do it the way it is shown in the documentation:
use strict; use warnings;
use Term::ReadLine;
my $term = Term::ReadLine->new('Text');
my $content = '';
while ( defined (my $con = $term->readline('input: ')) ) {
last unless length $con;
$content .= "$con\n";
}
print "You entered:\n$content\n";
Output:
C:\Temp> t
input: one
input: two
input:^D
You entered:
one
two