Why does perl remove the file extension when redirecting url via CMD? - perl

I am at age 13 attempting to learn Perl. Here is one of my first scripts. The link brings the user to a webpage which downloads an image. As some observant people may notice the link has the ending of .png which specifies the image in the url. When I run this script it opens Chrome, opens the url BUT fails to include the extension .png . My questions are:
A) Why is this happening?
B) Can anyone suggest an alternative and or fix my script.
The script is found here below.
#!/usr/bin/perl
print "Type Username Here:
";
$username = <>;
print "Link: http://s3.amazonaws.com/MinecraftSkins/$username.png
";
exec "start www.s3.amazonaws.com/MinecraftSkins/$username.png";
Please help!!!

When you capture the data, you are also capturing the new line at the end of it.
This gives you:
exec "start www.s3.amazonaws.com/MinecraftSkins/EXAMPLE
.png";
Remove the whitespace from the end of the entered data to avoid this.
$username =~ s/\s+$//;
or
chomp($username);

$username will include the carriage-return you hit when you hit "enter" at the input prompt, so your exec call actually looks like two separate commands:
start www.s3.amazonaws.com/MinecraftSkins/$username
.png
Try chomp($username) to strip off that whitespace.

You have to whipe the newline at end of your input:
#!/usr/bin/perl
print "Type Username Here:
";
chomp ( $username = <> );
print "Link: http://s3.amazonaws.com/MinecraftSkins/$username.png
";
exec "start www.s3.amazonaws.com/MinecraftSkins/$username.png";
You could sanitize (ensure that user input contain only letters, numbers and/or the character underscore _, for sample) you variable by:
#!/usr/bin/perl
print "Type Username Here:
";
$username = $1 if <> =~ /^([a-z0-9_]*)$/i;
print "Link: http://s3.amazonaws.com/MinecraftSkins/$username.png
";
exec "start www.s3.amazonaws.com/MinecraftSkins/$username.png";
Better written (as #KeithThompson comment):
#!/usr/bin/perl
print "Type Username Here:
";
if ( <> =~ /^([a-z0-9_]*)$/i ) {
$username = $1
print "Link: http://s3.amazonaws.com/MinecraftSkins/$username.png\n";
exec "start www.s3.amazonaws.com/MinecraftSkins/$username.png";
} else {
print "Error input contain invalid characters\n";
};

Related

How do I select text between two specific symbols in Perl?

I'm very new to Perl. I'm currently going through this Perl file and I've got this variable where I was able to format it down to get all the text after the "<" symbol using this line I found from another stackflow question.
($tempVariable) = $Line =~ /(\<.*)\s*$/;
So currently whenever I print this variable, I get the output
$tempVariable = <some text here #typeOf and more text here after
I need to get everything between the "<" symbol and the "#"symbol.
I tried looking at other stackflow questions and tried implementing it to mines but I keep getting errors so if anybody could help me out I would appreciate it.
my ($substr) = $str =~ /<([^<\#]*)\#/
or die "No match";
You'll need a regex that
looks for the starting < character
then (your question is unclear on this point)
captures one-or-more non-# characters, or
captures zero-or-more non-# characters
looks for the trailing # character
also not specified in your question: do you need to strip leading and trailing white space from the match?
I.e.
#!/usr/bin/perl
use warnings;
use strict;
my $Line = '<some text here #typeOf and more text here after';
my $tempVariable;
# alternative 1: one-or-more characters
($tempVariable) = $Line =~ /<([^#]+)#/
or die "No match alternative 1";
print "Alternative 1: '${tempVariable}'\n";
# alternative 2: zero-or-more characters
($tempVariable) = $Line =~ /<([^#]*)#/
or die "No match alternative 2";
print "Alternative 2: '${tempVariable}'\n";
exit 0;
Test run (white space is not stripped):
$ perl dummy.pl
Alternative 1: 'some text here '
Alternative 2: 'some text here '

Perl compiling errors

I seem to be getting some compiling errors i cannot figure out. any help would be greatly appreciated. the basic function of the program was created to manage a list of users.
the errors i am getting are:
C:\Users\mte>perl C:\Users\mte\Desktop\org11.pl
Unrecognized escape \m passed through at C:\Users\mte\Desktop\org11.pl line 2.
Unrecognized escape \D passed through at C:\Users\mte\Desktop\org11.pl line 2.
Unquoted string "pm" may clash with future reserved word at C:\Users\mte\Desktop\org11.pl line 3.
syntax error at C:\Users\mte\Desktop\org11.pl line 3, near "use org22."
syntax error at C:\Users\mte\Desktop\org11.pl line 119, near "$usernames1 ("
syntax error at C:\Users\mte\Desktop\org11.pl line 126, near "}"
Execution of C:\Users\mte\Desktop\org11.pl aborted due to compilation errors.
Here is the code.
use warnings;
use lib "C:\Users\mte\Desktop";
$nameoffile; #name of file
$filename; #the full path of the file
print "what is the name of the filename:", "\n";
$nameoffile = <>;
chomp($nameofile);
if (-e $nameoffile)
{
open ($filehandle, "<", $nameoffile);
}
else
{
open ($filehandle, ">", $nameoffile);
}
# load user accoutns from filefield;
%useraccountshash = ();
%useroptionsfunction = ('i' =>\&insert_user, 'm'=>\&modify_user,
'r'=>\&remove_user, 'g'=>\&generate_list);
while ($loadlines=<$filehandle>) # load all data into hash if the file already exists
{
# this array temporarily holds the user data while we prepare it to go to hash
#myarray = split(/:/, $loadlines); # split the line at the colon, will put username into index 0 in the array, and password in index 1
$username=$myarray[0];
$password=$myarray[1];
chomp($password);
$username=~ s/[^a-zA-Z0-9]//g;
$username=lc($username);
$password=~ s/\'//g;
# now we are putting in the user name and password into the hash , array to va, variiables, variables to hash
$useraccounthash{$username} = $password;
}
#user account interface
print "\t","\n","User Accounts","\n";
print "-------------","\n";
print "i = Insert new user account","\n";
print "m = modify existing user account","\n";
print "r = Remove existing user account","\n";
print "g = Generate list of accounts","\n";
print "q = Quit","\n","\n";
#userAccounts = ();
$userNameStorage;
#insert new user account interface
print("Enter Choice:");
while ($input != 'q')
{
while($input = <>) {
chomp $input;
if ($input eq "i"){
$command=$useroptionsfunction{i};
%useraccountshash=$command->(\%useraccountshash);
}
#modify username and password interface
elsif ($input eq "m"){
$command=$useroptionsfunction{m};
%useraccountshash=$command->(\%useraccountshash);
}
#remove the user interface
elsif ($input eq "r"){
$command=$useroptionsfunction{r};
%useraccountshash=$command->(\%useraccountshash);
}
#generate list of accounts
elsif ($input eq "g"){
$command=$useroptionsfunction{g};
%useraccountshash=$command->(\%useraccountshash);
}
elsif ($input eq "q"){
print "Quitting Program...";
}
}
}
close ($filehandle);
print "save changes? type, y or n";
$userinput=<>;
chomp($userinput);
if ($userinput eq 'y')
{
open ($filehandle, ">", $filename)
for $usernames1 (keys %useraccounthash)
{ # used to iterate through the hash and pull out usernames
print $filehandle "$usernames1:$useraccountshash{$usernames1}\n"; #goes
through keys and writes the key and value to file
}
close ($filehandle);
}
1;
The first problem is this line.
use lib "C:\Users\mte\Desktop";
In Perl, \ is an escape character. It's also used for special characters like \n (newline). Perl reads \U and \m and \D as special characters. While there is a \U, it does not understand the rest.
To avoid this, you need to escape the escape character.
use lib "C:\\Users\\mte\\Desktop";
syntax error at C:\Users\mte\Desktop\org11.pl line 119, near "$usernames1 ("
This is caused by a missing semi-colon on the previous line causing Perl to think the open and for loop are all one statement. Perl isn't good at detecting missing semi-colons; if a syntax error is puzzling, check the previous line.
The rest of your error messages are referring to code which you did not post.

Command line arguments are not working

I am using Perl for the first time.
I am writing two scripts, and one of those is being called from the other.
While I am passing arguments from user input it's giving an error, but if I hard code the values it works fine.
Please advise how to solve.
Code:
script.pl
use warnings;
my ($choice);
print("Hello!\n");
print("If you want to Generate Add, enter 1.\n");
print("If you want to exit,enter 2.\n");
$choice = <>;
chomp($choice);
if ($choice eq "1") {
print "Please enter 1st argument:";
$inputFile = <STDIN>;
print "Please enter 2nd argument:";
$outputFile = <STDIN>;
system($^X, "generateLdifAdd.pl", $inputFile, $outputFile);
}
elsif ($choice eq "2") {
exit();
}
else {
print("$choice is an invalid response.\n");
}
You probably need to chomp your input:
chomp($inputFile = <STDIN>);
chomp($outputFile = <STDIN>);
Also, don't forget to include use strict; at the top of every script along with use warnings;.
Someone's already mentioned needing to chomp your reads from STDIN.
Would I be right in thinking you've done a print on the values you got, and they're all looking good?
Can I suggest the next port of call is to check what command line you're passing to your second script?
I would suggest as simple as:
print "$^X generateLdifAdd.pl $inputFile $outputFile\n";
Check that looks right to you - gotchas might be that your 'other' script isn't in the path. Or that it's not correctly parsing your command line arguments. (You don't give an example, so it's hard to say). This would have also highlighted the problem with not using chomp - that your args contain linefeeds.

Attempting to pull just filename from backtick

I have an issue where I am attempting to pull just a filename from the output of running a backtick, my code is as follows:
$var = `munpack -f filename`;
If anyone is familiar with mpack the output will be something like:
tempdesc.txt: File exists
file_20130620.zip (application/octet-stream)
I am trying to just get the filename, however, all my attempted regexes have failed. I have even tried to just remove the linebreaks and then attempt to process the information and I cannot. I thought they could just be whitespace and remove the whitespace but those regexes have failed. I could go through and list every regex I have tried to pull this data and I can provide that if necessary, but maybe someone has something that could work. I can't produce any matches that id like nor alter the output in any way. So just to be clear im looking for something that will output me just the filename ex: file_20130620.zip
Some suggestions given with output:
$var =~ m{^(.+?)\(}m and print "$1\n";
output:
tempdesc.txt: File exists
file_20130620.zip
($filename) = $var =~ /(?s:.*\n)?(.*) \([^)]+\)\n/;
output:
tempdesc.txt: File exists
file_20130620.zip
if($var =~/\S+: [^\n]+\n(\S+) [^\n]+\n/) { printf $1; }
output:
tempdesc.txt: File exists
Fix per ysth:
$var = `munpack -f filename 2>/dev/null`; #will remove 'tempdesc.txt: File exists'
Assuming the filename is before a space before a parenthesized mimetype on the last line of output:
($filename) = $var =~ /(?s:.*\n)?(.*) \([^)]+\)\n/;
Though I'd rather create a temporary directory (use File::Temp) and unpack in it and just look for what file(s) are there than parse the output.
It is possible that the File Exists warning isn't actually in $var, but is appearing in your output because munpack is writing it to stderr (which doesn't get captured by backticks.)
Try doing munpack -q -f ... or munpack -f ... 2>/dev/null.
If you can assume that the filename is followed by a parenthesized description, something like this works:
$var =~ m{^(.+?)\(}m and print "$1\n";
The \m modifier treats a string as one with multiple lines so that you can match ^ and $ on any line. See perlre
I put your sample output to file1.txt as I dont have mpack utility installed.
And this regexp works
#!/usr/bin/perl
my $var = `more file1.txt`;
if($var =~/\S+: [^\n]+\n(\S+) [^\n]+\n/)
{
printf $1;
}

Why can't I match my string from standard input in Perl?

Why will my script not work correctly?
I follow a YouTube video and worked for the guy.
I am running Perl on Windows using ActiveState ActivePerl 5.12.2.1202
Here is my tiny tiny code block.
print "What is your name?\n";
$name = <STDIN>;
if ($name eq "Jon") {
print "We have met before!\n";
} else {
print "We have not met before.\n";
}
The code automatically jumps to the else statement and does not even check the if statement.
The statement $name = <STDIN>; reads from standard input and includes the terminating newline character "\n". Remove this character using the chomp function:
print "What is your name?\n";
$name = <STDIN>;
chomp($name);
if ($name eq "Jon") {
print "We have met before!\n";
} else {
print "We have not met before.\n";
}
The trick in programming is to know what your data are. When something's not acting like you expect, look at the data to see if they are what you expect. For instance:
print "The name is [$name]\n";
You put the braces around it so you can see any extra whitespace that might be there. In this case, you would have seen:
The name is [Jon
]
That's your clue that there is extra stuff. Since the eq has to match exactly, it fails to match.
If you're just starting with Perl, try Learning Perl. It's much better than random videos from YouTube. :)
When you read the name standard input as $name = <STDIN>;
$name will have a trailing newline. So if I enter foo , $name will actually have foo\n.
To get rid of this newline you an make use of the chomp function as:
chomp($name = <STDIN>);