wrong result with s command in perl - perl

Hi i want to find & replace some content of string
$source_folder = "D:\workdir\Devunit\11.1\latest";
$desitnation_folder = "D:\workdir\Devunit\10.1.3_Super\latest_Super";
$src_file = D:\workdir\Devunit\11.1\latest\src\tcbom\userver\buslogic\framework\bomitemfactory.cpp;
$dest_file = $src_file;
print " $dest_file \n";
$dest_file =~ s/$source_folder/$desitnation_folder/;
print " $dest_file \n";
both print results shows
D:\workdir\Devunit\11.1\latest\src\tcbom\userver\buslogic\framework\bomitemfactory.cpp
plz let me know where I am wrong

Use quotemeta if you don't want anything in your strings to be special, i.e. to have those interpreted literally. The following should work for you:
$source_folder = q(D:\workdir\Devunit\11.1\latest);
$desitnation_folder = q(D:\workdir\Devunit\10.1.3_Super\latest_Super);
$src_file = q(D:\workdir\Devunit\11.1\latest\src\tcbom\userver\buslogic\framework\bomitemfactory.cpp);
$dest_file = $src_file;
print " $dest_file \n";
$dest_file =~ s/\Q$source_folder\E/$desitnation_folder/;
print " $dest_file \n";
You might also want to refer to How do I match a regular expression that's in a variable?

Related

Split to get only characters in Perl

I have a string like this :
Reporting EXE1 BASE,Normal
I need to get a var for every words like :
$info = "Reporting";
$host = "EXE1";
$device = "BASE";
$status = "Normal";
In fact, i saw the function "Split" might be a good use, but i don't understand the patern to use.
I prefer to use a global regex pattern match instead of split. That way you can specify the characters that you're interested in instead of the ones that you want to discard, and there's no chance of a spurious initial empty field if your string happens to start with a separator
It looks like you want to pick out "word" characters, which are upper and lower case letters, decimal digits, and the underscore character. There's a built-in character class \w for that, so finding all sequences that match \w+ should find the data for you
Here's an example program
use strict;
use warnings 'all';
my $s = 'Reporting EXE1 BASE,Normal';
my ( $info, $host, $device, $status ) = $s =~ /\w+/g;
print qq{\$info = "$info"\n};
print qq{\$host = "$host"\n};
print qq{\$device = "$device"\n};
print qq{\$status = "$status"\n};
output
$info = "Reporting"
$host = "EXE1"
$device = "BASE"
$status = "Normal"
If you want to allow more characters than \w matches then you could use
my ( $info, $host, $device, $status ) = $s =~ /[^\s,]+/g;
which matches sequences of characters that are neither space nor comma
Given your sample data the results are identical, but I cannot tell what your real data looks like
Use split(/\s|,/,"Reporting EXE1 BASE,Normal") to split the string on comma and blank
You might try this code.
my $str = "Reporting EXE1 BASE,Normal";
my #fields = split /\s|,/, $str;
my $info = $fields[0];
my $host = $fields[1];
my $device = $fields[2];
my $status = $fields[3];
print "$info\n";
print "$host\n";
print "$device\n";
print "$status\n";
Or more compact version -
my $str = "Reporting EXE1 BASE,Normal";
my ( $info, $host, $device, $status ) = split /[\s,]/, $str ;
print "$info\n";
print "$host\n";
print "$device\n";
print "$status\n";
No need to store the data in an array. Directly create the list and give the variable name to it.
my $string = "Reporting EXE1 BASE,Normal";
my ($info ,$host,$device,$status) = split(/\s|,/,$string);
print "$info ,$host,$device,$status";
Or else you could use pattern matching
my ($info ,$host,$device,$status) = $string =~m/(\w+)/g;

Why is my string still empty?

I'm wondering why my string is still empty when just hitting enter after this code:
$file = <>;
if ($file eq "") {
$file = "test.txt";
}
print "$file";
If I type in anything, it is presented by the print command, but when I just hit enter, nothing is printed out. What I want is for perl to understand when the user inputs nothing and automatically edit the string to, in this case, test.txt. What am I doing wrong?
Thanks!
Because "enter" is not equal to nothing -- it's equal to \n.
$file = <>;
if ($file eq "") {
$file = "test.txt";
}
print length($file);
Run this, hit ENTER, and watch as you get -- 1!
Try:
$file = <>;
if ($file eq "\n") {
$file = "test.txt";
}
print "$file";
Bear in mind that \n isn't portable across systems. What you really want is something like:
$file = <>;
if ($file =~ /^\s*$/) {
$file = "test.txt";
}
print $file;
to match on whitespace.
To get the result you want you have to chomp your line.
use strict;
use warnings;
chomp(my $file = <>); #remove newline. $file will have empty string if only a newline was entered.
if ($file eq "") {
$file = "test.txt";
}
print "$file\n";

Comparing 2 strings, one from file and one declared

This program doesn't print that the strings are equal but when they get printed, they appear to be the same...someone please explain
#!/usr/bin/perl
$str = "print \"I want this to work\\n\";";
print $str."\n";
open FILE, "<", "check2.doc" or die "buhuhuhu";
my $str2;
while (<FILE>) {
$str2 = $_;
}
close FILE;
print "$str2\n";
if ( $str eq $str2) {
print "they are equal\n";
But when the output comes there is this extra line at the bottom due to the second string $str2
print "I want this to work\n";
print "I want this to work\n";
-----empty line-----
Here is the file check2.doc
print "I want this to work\n";
Does anyone know why they are not equal???
The file read includes the \n, so you have to remove it:
$str2 = $_;
chomp $str2;
And, if your file has only one line, replace the while loop by:
$str2 = <FILE>;
chomp $str2;
The line in the file is created by
$str."\n"
Of course that's not equal to
$str
You need to remove the trailing newline.
my $str2 = <FILE>;
chomp($str2);

Perl: Searching a file

I am creating a perl script that takes in the a file (example ./prog file)
I need to parse through the file and search for a string. This is what I thought would work, but it does not seem to work. The file is one work per line containing 50 lines
#array = < >;
print "Enter the word you what to match\n";
chomp($match = <STDIN>);
foreach $line (#array){
if($match eq $line){
print "The word is a match";
exit
}
}
You're chomping your user input, but not the lines from the file.
They can't match; one ends with \n the other does not. Getting rid of your chomp should solve the problem. (Or, adding a chomp($line) to your loop).
$match = <STDIN>;
or
foreach $line (#array){
chomp($line);
if($match eq $line){
print "The word is a match";
exit;
}
}
Edit in the hope that the OP notices his mistake from the comments below:
Changing eq to == doesn't "fix" anything; it breaks it. You need to use eq for string comparison. You need to do one of the above to fix your code.
$a = "foo\n";
$b = "bar";
print "yup\n" if ($a == $b);
Output:
yup

How can I separate a full path into directory and filename?

$a = '/etc/init/tree/errrocodr/a.txt'
I want to extract /etc/init/tree/errrocodr/ to $dir and a.txt to $file. How can I do that?
(Editor's note: the original question presumed that you needed a regular expression for that.)
Just use Basename:
use File::Basename;
$fullspec = "/etc/init/tree/errrocodr/a.txt";
my($file, $dir, $ext) = fileparse($fullspec);
print "Directory: " . $dir . "\n";
print "File: " . $file . "\n";
print "Suffix: " . $ext . "\n\n";
my($file, $dir, $ext) = fileparse($fullspec, qr/\.[^.]*/);
print "Directory: " . $dir . "\n";
print "File: " . $file . "\n";
print "Suffix: " . $ext . "\n";
You can see this returning the results you requested but it's also capable of capturing the extensions as well (in the latter section above):
Directory: /etc/init/tree/errrocodr/
File: a.txt
Suffix:
Directory: /etc/init/tree/errrocodr/
File: a
Suffix: .txt
you don't need a regex for this, you can use dirname():
use File::Basename;
my $dir = dirname($a)
however this regex will work:
my $dir = $a
$dir =~ s/(.*)\/.*$/$1/
I think a regex solution is a perfectly legitimate need - since my googling for exactly that brought me here. I want to pull out a filename in a group that's part of a larger match expression - here's my attempt:
~> echo "/a/b/c/d" | perl -ne '/(?<dir>\/(\w+\/)*)(?<file>\w+)/ && print "dir $+{dir} file $+{file}\n";'
dir /a/b/c/ file d
Use #array = split("/", $a);
and then $array[-1] is your file name.
For example:
$a =~ m#^(.*?)([^/]*)$#;
($dir,$file) = ($1,$2);
But, as other said, it's better to just use Basename for this.
And, BTW, better avoid $a and $b as variable names, as they have a special meaning, for sort function.
try this; it works at least for the filename, but when you modify it, it also gives you the direction:
You can also modify it on UNIX-systems for the \ instead if / or to use them both with |
$filename =~ s/(^.*/)//g;
somehow the backslash before the 2nd / is not displayed...
Maybe this will work:
#^(.+/)/([^/]+)$#