How do I concatenate string and convert to upper case - powershell

first sorry for my English.
I't use powershell but I have to make a script to generate some SSRS's reports. I need to concatenate two variables and convert the result to uppercase, the code below works fine but I't know convert the result to uppercase and put it, for example, into other variable. Thanks a lot
$direxcel = "C:\Users\Administrador\Documents\SSRS"
$rdl = "Sin Título"
write-host ${direxcel}\$rdl.xls

To concatenate strings you can use several options.
$a = "first string"
$b = "second string"
$c = "$a $b"
or simply (but not necessarily recommended)
$c = $a + $b
To make something upper case.
$c = "$a $b".ToUpper()

Related

How to convert string to int, if possible in powershell?

I am getting a string from VSO (using TFPT.exe) that can be either the item number or the item number plus a letter
"830" or "830a"
How can I break off the letter if it exists - and convert the number to int
$a = 830
#or
$a = 830
$b = "a"
I tried to test if "830" was a number - but i guess because it pulls it in as a string, i don't know how to ask: could this string be a int?
Assuming only the one set of numbers you can -match that pretty easily with regex. Where \d+ will match a group of consecutive digits.
PS C:\temp> "830a" -match "\d+"
True
PS C:\temp> $matches[0]
830
Knowing that you could incorporate something like this in your code.
$b = If($a -match "\d+"){[int]$matches[0]}
Obviously it would be more appropriate to use better variable names but this is just proof of concept. This as written would cause an issue if the alpha characters were in the middle of the string. As long as the number are grouped together it will work either way.
The other way you could do this would be to replace all of the character that are not digits.
$a = "830adasdf"
$a = $a -replace "\D" -as [int]
\D meaning any non digit character. -as [int] will perform the cast.
In either case [int] will cast the remaining digit string as an integer.
If you could guarantee that it is just the one character on the end that could be there then you could use the string method .TrimEnd() as well. It removes all characters found on the end of a string as determined by a char array. Lets give it an array of all letters. In practice this was having an issue with case so we take the string, converted it to uppercase and then remove any trailing letters.
"830z".ToUpper().TrimEnd([char[]](65..99)) -as [int]
It actually seems to convert the number array to char automatically so this would do just the same
"830z".ToUpper().TrimEnd(65..99) -as [int]
This is the best I have been able to come up with, seams to work: doesn't seam the most efficient way...
$t = $parent.Substring($parent.Length-1)
if($t -in #("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"))
{
[int]$parentSRP = $parent.Substring(0,$parent.Length-1)
$parentVer = $parent.Substring($parent.Length-1,1)
}
else{[int]$parentSRP = $parent}

What's the simplest way to represent a long string literal with simple pattern in Perl?

I have a long literal string in Perl, is there a way to represent it as simple pattern without typing it one by one? Such as some syntax as below.
$a = "abc" * 2; # $a gets "abcabc";
Use the x operator:
$a = "abc" x 2; # $a gets "abcabc";

Concatenating strings from a multidimensional array overwrites the target string in Perl

I've built a two dimension array with string values. There are always 12 columns but the number of rows vary. Now I'd like to build a string of each row but when I run the following code:
$outstring = "";
for ($i=0; $i < $ctrLASTROW + 1; $i++) {
for ($k=0; $k < 12; $k++){
$datastring = $DATATABLE[$i][$k]);
$outstring .= $datastring;
}
}
$outstring takes the first value. Then on the second inner loop and subsequent loops the value in $outstring gets overlaid. For example the first value is "DATE" then the next time when the value "ABC" gets fed to it. Rather than being the hoped for "DATEABC" it's "ABCE". The "E" is the fourth character of DATE. I figure I'm missing the scalar / list issue but I've tried who knows how many variations to no avail. When I first started I tried the concatenation directly from the #DATATABLE. Same problem. Only quicker.
When you have a problem such as two strings DATE and ABC being concatenated, and the end result is ABCE, or one of the strings overwriting the other, a likely scenario is that you have a file from another OS, with the line endings \r\n, which are chomped, resulting in the string DATE\rABC when concatenated, which then becomes ABCE when printed.
In other words:
my $foo = "DATE\r\n";
my $bar = "ABC\r\n"; # \r\n line endings from file
chomp($foo, $bar); # removes \n but leaves \r
print $foo . $bar; # prints ABCE
To confirm, use
use Data::Dumper;
$Data::Dumper::Useqq = 1;
print Dumper $DATATABLE[$i][$k]; # prints $VAR1 = "DATE\rABC\r";
To resolve, instead of chomp use a regex such as:
$foo =~ s/[\r\n]+\z//;

Identify empty string in Perl

There is probably an easy solution to this, but I can't figure it out. I am looking to:
take a CSV file into an array
loop through the array and split fields into variables
if the array field is empty then set the variable to "N/A"
Note: It is only setting the $variable to "N/A" that I cannot get working.
For example:
foreach $var (#list) {
($name,$date,$size, etc...)=split(/,\"/,$var);
}
How would I set $date to "N/A" if the field in the array is empty?
so to produce:
$name = Jim
$date = N/A
$size = small
I hope this makes sense and is easy to fix.
-Thanks
Assuming the variable $date is undefined when "empty":
if (!defined($date)) {
$date = 'N/A';
}
Or more concisely:
$date //= 'N/A';
Or if it really is an empty string, i.e. $date = ''; (this will also work in the case where $date is undefined, but you don't want to use this if you only want to identify the case where it is undefined):
if ($date eq '') {
$date = 'N/A';
}
Or more concisely (note that this will also set $date to N/A if $date is '0' due to Perl's weak typing):
$date ||= 'N/A';
As far as your third bullet point and the actual question: to check for emptiness:
For empty string, you can either do the above-mentioned eq "", or you can check the string length: $var = "N/A" unless length($var);;
For an undefined of empty string, in Perl 5.10 you can use the "defined-or" (//) operator to do the short version: $var = "N/A" unless length($var // '');
In Perl before 5.10 where "defined-or" is not available, you will either have to spell out the defined check: $var = "N/A" unless defined $var && length($var);
... or, you can just stop caring about undefined warnings by turning them off (h/t brian d foy):
no warnings 'uninitialized';
$_ = "N/A" unless length($_) foreach ($name,$date,$size, etc...);
use warnings 'uninitialized'; # Always turn back on.
However, please note that you also should consider a different approach to the first two bullet points. Implementing your own CSV parser which is 100% correct is not trivial - for example, your sample code will break if any of the fields contain a double quote.
Instead, you should always use one of the standard Perl CSV parsers, such as Text::CSV_XS.
$name = "N/A" if (!defined($name) || ($name eq ""))
$date = "N/A" if (!defined($date) || ($date eq ""))
$size = "N/A" if (!defined($size) || ($size eq ""))
Make sure you are using string comparison for comparing strings :)
What will be the input like if date is missing? If the input is: somename,200 (where 200 is size), then date would be set as 200 right?
If the input is like this
somename,,200
where 200 is size, and because date is unavailable it is set to empty. Then you can do a simple if-check:
if($date eq '')
{
$date = "NA";
}
Note $date will be defined, it will be just set to empty
if ($date eq '') { print "STRING IS EMPTY\n" } else { Print "STRING IS NOT EMPTY\n";}
we can use the above code to identify the empty string ,and using the regular expression is more efficient. The "=~" operator and using regular expression also we can also this problem.

Perl pack/unpack/shift

I've been having this problem in Perl for a few days now, and after scouring countless man pages, perldocs and googling too many search terms, hopefully someone here can help me out.
I am given two strings which represent hex values, i.e. "FFFF", not the Perl hex number 0xFFFF. Given two of these strings, I wish to convert them to binary form, perform a bitwise AND of the two, then take the output of this and examine each bit from LSB to MSB.
I have two problems right now; converting the hex string into a hex number, and shifting
the result of the bitwise AND.
For converting the hex string into a hex number, I've tried the following approaches which don't seem to work when I print them out to examine:
$a = unpack("H*", pack("N*", $a));
$a = sprintf("%H", $a);
Using a 'print' to examine each of these does not show a correct value, nor does using 'sprintf' either...
The second problem I have occurs after I perform a bitwise AND, and I want to examine each bit by shifting right by 1. To avoid the previous problem, I used actual Perl hex numbers instead of hex strings (0xffff instead of "ffff"). If I try to perform a shift right as follows:
#Convert from hex number to binary number
$a = sprintf("%B", $a);
$b = sprintf("%B", $b);
$temp = pack("B*", $a) & pack("B*", $b);
$output = unpack("B*", $temp);
At this point everything looks fine, and using a 'print' I can see that the values of the AND operation look right, but when I try to shift as follows:
$output = pack("B*", $output);
$output = $output >> 1;
$output = unpack("B*", $output);
The resulting value I get is in binary form but not correct.
What is the correct way of performing this kind of operation?
There's no such thing as a "hex number". A number is a number, a hexadecimal representation of a number is just that - a representation.
Just turn it into a number and use bitwise and.
my $num = (hex $a) & (hex $b);
print ($num & 1, "\n") while ($num >>= 1)