I am trying to get "loginuser" value from this line. Please suggest
my $ln = CN=xuser\\,user(loginuser),OU=Site-Omg,OU=Accounts_User,OU
if (/ln: (\S.*\S)\s*$/)
{ print $1; }
This will work
use strict;
use warnings;
my $ln = qq{CN=xuser\\,user(loginuser),OU=Site-Omg,OU=Accounts_User,OU};
print $1 . "\n" if $ln =~ /\(([^)]*)/
Things to note
I have used strict and warnings to show any errors in the script( would have been very useful for your original)
I have used qq{...} to quote the original string
I have ended the line with ;
I have performed the regex match on $ln instead of $_ using $ln =~ ...
I have written correct regex to get the match.
Related
I am very new to Perl. Trying to grep the full line for matched pattern of the string. Seems like it is not able to search for full string. Any suggestion?
use strict;
use warnings;
my $prev;
#my $pattern = ":E: (Sub level extra file/dir checks):";
open(INPUTFILE, "<log_be_sum2.txt") or die "$!";
open(OUTPUTFILE, ">>extract.txt") or die "$!";
while (<INPUTFILE>){
if ($_ =~ /^:E: (Sub level extra file/dir checks):/){
print OUTPUTFILE $prev, $_;
}
$prev = $_;
}
If you want to match a literal / in a regular expression, it either needs to be escaped with a backslash, or you need to use a different character as the regexp quote character (! in the below example). The parenthesis also have to be escaped so they're not treated as a capturing group:
use strict;
use warnings;
my $prev;
#my $pattern = ":E: (Sub level extra file/dir checks):";
open(INPUTFILE, "<", "log_be_sum2.txt") or die "$!";
open(OUTPUTFILE, ">>", "extract.txt") or die "$!";
while (<INPUTFILE>){
if ($_ =~ m!^:E: \(Sub level extra file/dir checks\):!){
print OUTPUTFILE $prev, $_;
}
$prev = $_;
}
Note the change to the three-argument version of open, which is highly recommended. Might consider lexical file handles too. And good for you for using warnings and strict mode! Don't see that enough in new users of the language.
It's good that you are using strict and warnings but you should pay attention to the error/warning messages, and post them along with the question if you don't understand them. My version of Perl fails with an error about an unmatched (. The reason this particular error is thrown is because Perl thinks your regexp is complete when it sees the "/" in "file/dir".
When you have special characters, a good practice is to use quotemeta. I noticed you have a commented line with a variable assignment to pattern. You could uncomment that and use it like this:
...
my $pattern = quotemeta ":E: (Sub level extra file/dir checks):";
...
if ($_ =~ /^$pattern/){
...
}
...
}
But there is also a shortcut documented in perlre: the \Q and \E escape sequences. You can use it like $_ =~ /^\Q$pattern\E/. You can still use it and avoid the variable assignment, but in your case you will need to use a different character for the quote-like operator, since your pattern contains a literal /. I tend to prefer m{}, but it's really up to you as long as it's not /.
use strict;
use warnings;
my $prev = q{}; # NOTE: see NOTE below
open INPUTFILE, "<", "log_be_sum2.txt" or die "$!";
open OUTPUTFILE, ">>", "extract.txt" or die "$!";
while (<INPUTFILE>){
if ($_ =~ m{^\Q:E: \(Sub level extra file/dir checks\):\E}){
print OUTPUTFILE $prev, $_;
}
$prev = $_;
}
*NOTE - I seeded $prev with an empty string, because otherwise if your match is on the first line, you will try to print an undefined value, which will result in a warning.
How to simply do a search/replace in Perl? The following example doesn't work:
#!/usr/bin/env perl
use strict;
use warnings;
my $text = '***/**/*abc*/***//*';
my $search = '/*abc*/';
my $replace = '#def#';
print "$text\n";
$text =~ s/$search/$replace/g;
print "$text\n";
$search is not treated as a string, but as a regular expression. The character * has a special meaning in regular expressions so you need to quote it. Try:
$search = quotemeta '/*abc*/';
Make sure that content of $search has quoted meta-chars by using \Q or quotemeta in order to be treated as literal string,
$text =~ s/\Q$search/$replace/g;
I am trying to run the following code:
$lines = "Enjoyable )) DAY";
$lines =~ lc $lines;
print $lines;
It fails on the second line where I get the error mentioned in the title. I understand the brackets are causing the trouble. I think I could use "quotemeta", but the thing is that my string contains info that I go on to process later, so I would like to keep the string intact as far as possible and not tamper with it too much.
You have two problems here.
1. =~ is used to execute a specific set of operations
The =~ operator is used to either match with //, m//, qr// or a string; or to substitute with s/// or tr///.
If all you want to do is lowercase the contents of $lines then you should use = not =~.
$lines = "Enjoyable )) DAY";
$lines = lc $lines;
print $lines;
2. Regular expressions have special characters which must be escaped
If you want to match $lines against a lower case version of $Lines, which should return true if $lines was already entirely lower case and false otherwise, then you need to escape the ")" characters.
#!/usr/bin/env perl
use strict;
use warnings;
my $lines = "enjoyable )) day";
if ($lines =~ lc quotemeta $lines) {
print "lines is lower case\n";
}
print $lines;
Note this is a toy example trying to find a reason for doing $lines =~ lc $lines - It would be much better (faster, safer) to solve this with eq as in $lines eq lc $lines.
See perldoc -f quotemeta or http://perldoc.perl.org/functions/quotemeta.html for more details on quotemeta.
=~ is used for regular expressions. "lc" is not part of regex, it's a function like this: $new = lc($old);
I don't recall the regex operator for lowercase, because I use lc() all the time.
I am using Perl to replace all instances of
../../../../../../abc' and
in a string with
/ and , respectively.
The method I am using looks like this:
sub encode
{
my $result = $_[0];
$result =~ s/..\/..\/..\/..\/..\/..\//\//g;
$result =~ s/ / /g;
return $result;
}
Is this correct?
Essentially, yes, although the first regex has to be written in a different way: because . matches any character, we have to escape it \. or put it in its own character class [.]. The first regex can also be written cleaner as
...;
$result =~ s{ (?: [.][.]/ ){6} }
{/}gx;
...;
We look for the literal pattern ../ repeated 6 times and then replace it. Because I use curly braces as a delimiter I don't have to escape the slash. Because I use the /x modifier I can have these spaces inside the regex improving readability.
Try this. It will print /foo bar/baz.
#!/usr/bin/perl -w
use strict;
my $result = "../../../../../../foo bar/baz";
#$result =~ s/(\.\.\/)+/\//g; #for any number of ../
$result =~ s/(\.\.\/){6}/\//g; #for 6 exactly
$result =~ s/ / /g;
print $result . "\n";
you forgot the abc, i think:
sub encode
{
my $result = $_[0];
$result =~ s/(?:..\/){6}abc/\//g;
$result =~ s/ / /g;
return $result;
}
I have a variable how do I use the regex in perl to check if a string has spaces in it or not ? For ex:
$test = "abc small ThisIsAVeryLongUnbreakableStringWhichIsBiggerThan20Characters";
So for this string it should check if any word in the string is not bigger than some x characters.
#!/usr/bin/env perl
use strict;
use warnings;
my $test = "ThisIsAVeryLongUnbreakableStringWhichIsBiggerThan20Characters";
if ( $test !~ /\s/ ) {
print "No spaces found\n";
}
Please make sure to read about regular expressions in Perl.
Perl regular expressions tutorial - perldoc perlretut
You should have a look at the perl regex tutorial. Adapting their very first "Hello World" example to your question would look like this:
if ("ThisIsAVeryLongUnbreakableStringWhichIsBiggerThan20Characters" =~ / /) {
print "It matches\n";
}
else {
print "It doesn't match\n";
}
die "No spaces" if $test !~ /[ ]/; # Match a space
die "No spaces" if $test =~ /^[^ ]*\z/; # Match non-spaces for entire string
die "No whitespace" if $test !~ /\s/; # Match a whitespace character
die "No whitespace" if $test =~ /^\S*\z/; # Match non-whitespace for entire string
To find the length of the longest unbroken sequence of non-space characters, write this
use strict;
use warnings;
use List::Util 'max';
my $string = 'abc small ThisIsAVeryLongUnbreakableStringWhichIsBiggerThan20Characters';
my $max = max map length, $string =~ /\S+/g;
print "Maximum unbroken length is $max\n";
output
Maximum unbroken length is 61