How to process a file in Perl - handling variables from Bash: disappearing "." character - perl

I need to find the age of a file in seconds but when I give my Perl line:
perl -e ' my #st=stat("$name"); print time - $st[9];'
a variable from Bash with "." in the filename, it won't find the file and prints the systime instead. Otherwise, if I create a file with a name such "something", it works perfectly well.
I tried escaping the character with \ but that does not work. I really do not know Perl and I don't know how to figure this out.
Thanks for the help!
(Please, do not suggest any BASH only workarounds, lot of stuff here is old, truncated...)
EDIT: I found a workaround but I can't post an answer to my own question since I am a newbie, so here it is:
So I finally found a workaround.
You export the variable in Bash:
export name=".file.txt"
and then call it from the Perl like this: $ENV{name}
and it works just fine.
EDIT 2:
The export idea was just a temporary solution. Better one is using single quotes as perreal suggested.

You need to put the shell variable out of the single quotes:
perl -e ' my #st=stat("'"$name"'"); print time - $st[9];'
or pass it through arguments:
perl -se 'my #st=stat("$name"); print time - $st[9];' -- -name="$name"

Related

sed system command in perl script

I am trying to put the system command like below to the perl script, but
sed expression contains both quotes and backticks and I am not sure how to escape all of them, so it will execute my system command exactly as I need.
Here is the example of the command:
mysql -u root -D porta-billing -e "..." | sed "s/'/\'/;s/\t/\",\"/g;s/^/\"/;s/$/\"/;s/\n//g"
The answer to the question you're asking is to use the qx(...) operator. qx(...) is the "choose your own delimiter" version of backticks.
my $output = qx[ ... ];
Or
my $output = qx( ... );
Or
my $output = qx! ... !;
It's easy to find a delimiter that won't clash with the characters in your command string.
But the answer to the question that you should be asking has two parts:
Don't call mysql from your Perl program - use DBI instead.
Don't call sed from your Perl program - use Perl code to manipulate your text.
I feel slightly nervous about the first part of my answer as I'm worried you will just take my hacky workaround and end up with an unmaintainable mess. Please take note of the advice in the second half - even if you ignore it in this case.

How to decode Acme::Eyedrops

How do I get readable code back from an Acme::Eyedrops obfuscated script?
From the documentation, it looks like sightly_to_ascii might work.
use B::Deparse (as in perl -MO=Deparse proggram.pl ) and/or replace eval with print, depending on which pattern eyedrops generates
Late answer, but for anyone finding this via Google, installing PerlTidy from SourceForge and then running the following command line worked like a charm for me:
perl -MO=Deparse /path/to/ObfuscatedScript.pl | perltidy > new.pl
This created a file called new.pl within my current directory with the
acme::eyedrops code deobfuscated.

parsing first entry of a find call in perl?

I need to get an example file file from a find command in a Perl script to create another system call afterwards. For some reason, the find command gets stuck when I call it from the script. Here is what I need to do:
my $search_dir = "/something/like/this/??/??/??";
# the triple '??' are needed here
my $cmd = "find $search_dir -name \"\*.$var1.token1.$var2.ext\" | head -n 1";
my $first_example_file = `$cmd`; chomp $first_example_file;
This gets stuck when I run it through Perl, it never finishes executing the command, whereas the constructed $cmd runs in no time if I copy+paste it and run in in my bash terminal. Any ideas?
Try using the File::Find perl module for finding files. If you would like to use bash's find in your perl then you might have to use $(..) in your command.
I am not in to perl … just trying to help out.
Update:
As stated in the comments by Rohaq you can also use File::Find::Rule
I'd wager globbing (shell metacharacter expansion) is involved. But regardless, try and chop the command up. Does it work without the pipe? What about without the ?? in the pathname? What happens if you prepend 'echo' ("echo find ...")? Still hanging? Then you can try it under perl -d - the debugger; perldoc perldebug is your friend.

replacing a variable in shell script using perl

I have a variable in a shell script,
var=1234_number
I want to replace all other than integer of $var .. how can I do it using a perl onliner?
You might be looking for something to edit the shell script, in which case, this might be sufficient:
perl -i.bak -e 's/\b(var=\d+).*/$1/' shellscript.sh
The '-i' overwrites the original file, saving a copy in shellscript.sh.bak; the substitute command finds assignments to 'var' (and not any longer name ending 'var') followed by an equals sign, some digits, and any non-digits, and leaves behind just the assignment of digits.
In the example, it gives:
var=1234
Note that the Perl regex is not foolproof - it will mangle this (dropping the closing brace).
: ${var=1234_number}
Dealing with all such possible variants is extremely fairly tricky:
echo $var=$other
OTOH, you might be looking to eliminate digits from a variable within a shell script, in which case:
var=$(echo $var | perl -e 's/\D//g')
You could also use 'sed' for the job:
var=$(echo $var | sed 's/[^0-9]//g')
No need to use anything but the shell for this
var=1234_abcd
var=${var%_*}
echo $var # => 1234
See 'Parameter Expansion' in the bash manual.

Why does TextMate always complain 'Can't find string terminator '"'' when it runs a Perl script?

I have a long-ish Perl script that runs just fine, but always gives this warning:
Can't find string terminator '"' anywhere before EOF at -e line 1
I've read elsewhere online that this is because of a misuse of single or double quotes and the error generally stops the script from running, but mine works. I'm pretty sure I've used my quotes correctly.
Is there anything else that could cause this warning?
EDIT:
I'm running the script via TextMate, which may be spawning a new Perl process to run my script.
I actually get the error when I run simple scripts as well, like this one:
#!/usr/bin/perl -w
use strict;
use warnings;
print "Hello world.";
Yes, you are right, your script does that in TextMate when I try it too.
Simple solution: don't run it using TextMate; just use the command line:
cd Projectdirectory
chmod +x myscript.pl
./myscript.pl
Hello world
More complex solution: tell TextMate that their application is broken and wait for them to fix it. The error is coming from some other Perl script that TextMate is invoking. Even a completely blank file run as Perl in TextMate fails with this error.
-Alex
The "at -e line 1" bit means it's coming from a one-liner. I suspect your long script is somewhere starting a separate perl process (possibly indirectly), and that perl is what is giving the error (and not doing whatever it is supposed to do.)
Start the debugger by doing
perl -d ./youscript.pl
Then keep pressing n[ENTER] (or just ENTER after you press n once) until you see the warning - the line that was just executed is your culprit. n stands for the next debugger directive btw.