need help on Regular expression - perl

We have a file with below syntax:
I/P : abc_com.an.gx3d_02-20-2014_05-26-38.txt
O/P : abc_com.an.gx3d
I am trying to remove the part which starts with a timestamp. I tried with the below code but it's not working:
(my $test = $file) =~ s/^\d{2}\.*//;

Your ^ anchor is forcing your regex to only match at the beginning of the string. You probably want something closer to the following:
(my $test = $file) =~ s/_\d{2}-\d{2}-\d{4}_.*//;

Related

Extract the numbers at the end from a file name using perl

I am unable to extract the last digits in the filename and rename the file placing the digits at the beginning of the file.
Like suppose my file name is "Gen_TCC_TIF_2110_413010_L3TL_Ae6TL707285_371925.out"
I want to rename the file as "371925_Gen_TCC_TIF_2110_413010_L3TL_Ae6TL707285.out"
my $newFileName ='Gen_TCC_TIF_2110_413010_L3TL_Ae6TL707285_371925.out';
my ($digits) = $newFileName =~ /(\d+)/g;
my $newFileName_2="${digits}_Gen_TCC_TIF_2110_413010_L3TL_Ae6TL707285_371925.out"
try:
$newFileName =~ /(\d+)\.out/;
my $digits = $1;
my $newFileName_2=$digits."_Gen_TCC_TIF_2110_413010_L3TL_Ae6TL707285_371925.out";
(\d+)\.out/ should give you all Digits before .out
Try this:
$newFileName =~ s/(.*?)_(\d+)\.out/$2_$1\.out/;
Or
$newFileName =~ s/(.*?)_(\d+)(\.\w+)/$2_$1$3/;
You can do it with a single regex:
my $newFileName = 'Gen_TCC_TIF_2110_413010_L3TL_Ae6TL707285_371925.out';
my $newFileName_2 = $filename =~ s/(.*)_(\d+)(?=\.out)/$2_$1/r;
# or, for older Perl, use this instead:
(my $newFileName_2 = $filename) =~ s/(.*)_(\d+)(?=\.out)/$2_$1/;
# or, to modify directly the variable $newFileName:
$newFileName =~ s/(.*)_(\d+)(?=\.out)/$2_$1/;
Or if you want to get the digits (because you need them for something else), then you can do:
my ($digits) = $newFileName =~ /_(\d+)\.out/;
You were using /g modifier, which made your regex match all blocks of digits, which isn't what you wanted. (even worst, it was returning an array, but you were only keeping the first element (2110) in the scalar $digit )

How to regex one word from escaped and closed parenthesis?

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.

Perl, ne operator not working

Can someone please tell me why my ne operator isn't working in the below if statement? It was working but after saving my program, it has stopped working. Any help would be greatly appreciated, cheers.
$inFile = "animals.txt";
open (IN, $inFile) or
die "Can't find file: $inFile";
#animallist = (<IN>);
foreach $line (#animallist)
{
if ($line =~ $search)
{
print "$line <br> <br>";
}
}
if ($line ne $search)
{
print "$search isn't in the animal list";
}
print end_html;
You seem confused about what your program does, so I thought I'd just tell you.
$inFile = "animals.txt";
open (IN, $inFile) or die "Can't find file: $inFile";
#animallist = (<IN>);
# here you define a file name, open a file, and read all of the lines
# in the file into the array #animallist
foreach $line (#animallist) {
# here you iterate over all the lines, putting each line into $line
if ($line =~ $search) {
print "$line <br> <br>";
}
# here you perform the regex match: $line =~ /$search/ and if it
# succeeds, print $line
}
# here you end the loop
if ($line ne $search) {
print "$search isn't in the animal list";
}
# here you take the now uninitialized variable $line and try to match
# it against the as of yet undefined variable $search
# If both of these variables are undefined, and you are not using warnings
# it will simply return false (because "" ne "" is false)
# without warning about undefined variables in ne
You should be aware that even if your entire line was, for example, cat, you still could not compare it using ne to the string cat, because when read from a file, it has a trailing newline, so it is really cat\n. Unless you chomp it.
It seems redundant to tell you, but of course you cannot check if the file does not contain $search after you finished reading the file. You have to do that while reading the file.
Try using indentation so you can see when your blocks end at inappropriate places.
if ($line ne $search) isn't even within the foreach loop where you are populating and handling $line from the file. I suggest putting it within the block to at least get the functionality I assume you are looking for.
It's hard to know what you expect to happen as we don't know what $search contains. Let's assume it's the name of an animal that is in your file.
When you execute your code, $search contains, say, "frog" and $line contains undef (as $line only contains data within your foreach loop). Those values aren't the same so the ne returns true and the message is printed.
If you were to move that if statement into the foreach block then $line would have a value. But it still wouldn't match as lines are read from a file with the newline character still attached. And "Frog" is not the same as "Frog\n". You need to use chomp() to remove the newline from $line.
This is very similar to another recent question. Are you working on the same piece of homework?
I think there are several points here:
For the if ($line ne $search), the $line is out of the scope of the foreach where it was declared and since you are not using strict, you won't get error and this condition should always be true.
I assume that $line has a newline so when you match this $line with $search, the condition can be true although the strings are not equal.
Assuming that $line = "lion\n" and $search = "lion"
then if you do if ($line =~ $search), the condition will be be true, because "lion" is part of the "lion\n" string. This means that:
if ($line eq $search) is false
and if ($line ne $search) is true which I assume is your case.
you can use the chomp($line) function to remove newlines from the end of the string.
I hope this helps.

Unmatched ) in reg when using lc function

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.

Rename a file with perl

I have a file in a different folder I want to rename in perl, I was looking at a solution earlier that showed something like this:
#rename
for (<C:\\backup\\backup.rar>) {
my $file = $_;
my $new = $file . 'backup' . $ts . '.rar';
rename $file, $new or die "Error, can not rename $file as $new: $!";
}
however backup.rar is in a different folder, I did try putting "C:\backup\backup.rar" in the <> above, however I got the same error.
C:\Program Files\WinRAR>perl backup.pl
String found where operator expected at backup.pl line 35, near "$_ 'backup'"
(Missing operator before 'backup'?)
syntax error at backup.pl line 35, near "$_ 'backup'"
Execution of backup.pl aborted due to compilation errors.
I was using
# Get time
my #test = POSIX::strftime("%m-%d-%Y--%H-%M-%S\n", localtime);
print #test;
To get the current time, however I couldn't seem to get it to rename correctly.
What can I do to fix this? Please note I am doing this on a windows box.
Pay attention to the actual error message. Look at the line:
my $new = $_ 'backup'. #test .'.rar';
If you want to interpolate the contents of $_ and the array #test into a string like that, you need to use:
my $new = "${_}backup#test.rar";
but I have a hard time making sense of that.
Now, strftime returns a scalar. Why not use:
my $ts = POSIX::strftime("%m-%d-%Y--%H-%M-%S", localtime);
my $new = sprintf '%s%s%s.rar', $_, backup => $ts;
Incidentally, you might end up making your life much simpler if you put the time stamp first and formatted it as YYYYMMDD-HHMMSS so that there is no confusion about to which date 04-05-2010 refers.
The line
my $new = $_ 'backup'. #test .'.rar';
probably should read
my $new = $file . 'backup' . #test . '.rar';
(You were missing a concatenation operator, and it is clearer to use the named variable from the line before than reusing $_ there...)
I think you missed the string concat symbol . (the period) :
my $new = $_ 'backup'. #test .'.rar';
should be
my $new = $_ . 'backup' . #test . '.rar';
A slight side issue but you don't need
for (<C:\\backup\\backup.rar>) {
my $file = $_;
.....
}
The < > construct would be useful if you were expanding a wildcard but you are not.
Be thoughtful of future readers of this code (you in a year!) and write
my $file = 'C:\backup\backup.rar' ;
Note the single quotes which doen't expand backslashes.