Powershell Split String with "-" and number - powershell

$string = abc_test.txt-1234.xml
trying to split it "-" and any number,
so that
first part after split would be abc_test.txt
I tried below.
$new = $string -Split'(?=\d)'
$new[0]

Add the dash to your -split:
$new = $string -Split'(?=-\d)'

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 )

Split to get only characters in Perl

I have a string like this :
Reporting EXE1 BASE,Normal
I need to get a var for every words like :
$info = "Reporting";
$host = "EXE1";
$device = "BASE";
$status = "Normal";
In fact, i saw the function "Split" might be a good use, but i don't understand the patern to use.
I prefer to use a global regex pattern match instead of split. That way you can specify the characters that you're interested in instead of the ones that you want to discard, and there's no chance of a spurious initial empty field if your string happens to start with a separator
It looks like you want to pick out "word" characters, which are upper and lower case letters, decimal digits, and the underscore character. There's a built-in character class \w for that, so finding all sequences that match \w+ should find the data for you
Here's an example program
use strict;
use warnings 'all';
my $s = 'Reporting EXE1 BASE,Normal';
my ( $info, $host, $device, $status ) = $s =~ /\w+/g;
print qq{\$info = "$info"\n};
print qq{\$host = "$host"\n};
print qq{\$device = "$device"\n};
print qq{\$status = "$status"\n};
output
$info = "Reporting"
$host = "EXE1"
$device = "BASE"
$status = "Normal"
If you want to allow more characters than \w matches then you could use
my ( $info, $host, $device, $status ) = $s =~ /[^\s,]+/g;
which matches sequences of characters that are neither space nor comma
Given your sample data the results are identical, but I cannot tell what your real data looks like
Use split(/\s|,/,"Reporting EXE1 BASE,Normal") to split the string on comma and blank
You might try this code.
my $str = "Reporting EXE1 BASE,Normal";
my #fields = split /\s|,/, $str;
my $info = $fields[0];
my $host = $fields[1];
my $device = $fields[2];
my $status = $fields[3];
print "$info\n";
print "$host\n";
print "$device\n";
print "$status\n";
Or more compact version -
my $str = "Reporting EXE1 BASE,Normal";
my ( $info, $host, $device, $status ) = split /[\s,]/, $str ;
print "$info\n";
print "$host\n";
print "$device\n";
print "$status\n";
No need to store the data in an array. Directly create the list and give the variable name to it.
my $string = "Reporting EXE1 BASE,Normal";
my ($info ,$host,$device,$status) = split(/\s|,/,$string);
print "$info ,$host,$device,$status";
Or else you could use pattern matching
my ($info ,$host,$device,$status) = $string =~m/(\w+)/g;

How do edit the last occurrence of a particular string in powershell

My text file contains G-Code with the code "G94" appearing 5 times at different line numbers.
G94
G94
G94
G94
G94
I need to change the last occurrence of "G94" to
G94
/M16
but I keep getting no edit at all.
I'm trying this:
$text = get-content C:\cncm\g94.txt
$i = 1
$replace = 5 #Replace the 5th match
ForEach ( $match in ($text | select-String "G94" -AllMatches).matches)
{
$index = $match.Index
if ( $i -eq $replace )
{
$text.Remove($index,"G94".length).Insert($index,"G94 n /M16")
}
$i++
}
What am I missing?
$text is an array of strings, how are you calling Remove() without getting an exception? First because Remove() only takes one parameter, second because you can't remove from a fixed length array.
I'm thinking:
$text = get-content C:\cncm\g94.txt
$fifthMatch = ($text | select-string "G94" -AllMatches)[4]
$line = $text[$fifthMatch.LineNumber]
$line = $line.Remove($fifthMatch.index,"G94".length).Insert($fifthMatch.index,"G94 `n /M16")
$text[$fifthMatch.LineNumber] = $line
$text | out-file c:\cncm\g942.txt
Use regexp with negative lookahead on a string that contains the entire file.
Replacing last occurrence in the entire file - (?s) DOTALL mode allows .* to span across new line characters:
$text = [IO.File]::ReadAllText('C:\cncm\g94.txt')
$text = $text -replace '(?s)G94(?!.*?G94)', "G94`n/M16"
Replacing last occurrence in every line - (?m) MULTILINE mode:
$text = [IO.File]::ReadAllText('C:\cncm\g94.txt')
$text = $text -replace '(?m)G94(?!.*?G94)', "G94`n/M16"

A Perl Program Which divides a String by spaces between them?

I want my program to divide the string by the spaces between them
$string = "hello how are you";
The output should look like that:
hello
how
are
you
You can do this is a few different ways.
use strict;
use warnings;
my $string = "hello how are you";
my #first = $string =~ /\S+/g; # regex capture non-whitespace
my #second = split ' ', $string; # split on whitespace
my $third = $string;
$third =~ tr/ /\n/; # copy string, substitute space for newline
# $third =~ s/ /\n/g; # same thing, but with s///
The first two creates arrays with the individual words, the last creates a different single string. If all you want is something to print, the last will suffice. To print an array do something like:
print "$_\n" for #first;
Notes:
Normally, regex capture requires parentheses /(\S+)/, but when the /g modifier is used, and parentheses are omitted, the entire match is returned.
When using capture this way, you need to assure list context on the assignment. If the left hand parameter is a scalar, you would force list context with parentheses: my ($var) = ...
I think like simple....
$string = "hello how are you";
print $_, "\n" for split ' ', $string;
#Array = split(" ",$string); then the #Array contain the answer
You need a split for dividing the string by spaces like
use strict;
my $string = "hello how are you";
my #substr = split(' ', $string); # split the string by space
{
local $, = "\n"; # setting the output field operator for printing the values in each line
print #substr;
}
Output:
hello
how
are
you
Split with regexp to account for extra spaces if any:
my $string = "hello how are you";
my #words = split /\s+/, $string; ## account for extra spaces if any
print join "\n", #words

How to substitute arbitrary fixed strings in Perl

I want to replace a fixed string within another string using Perl. Both strings are contained in variables.
If it was impossible for the replaced string to contain any regex meta-characters, I could do something like this:
my $text = 'The quick brown fox jumps over the lazy dog!';
my $search = 'lazy';
my $replace = 'drowsy';
$text =~ s/$search/$replace/;
Alas, I want this to work for arbitrary fixed strings. E.g., this should leave $text unchanged:
my $text = 'The quick brown fox jumps over the lazy dog!';
my $search = 'dog.';
my $replace = 'donkey.';
$text =~ s/$search/$replace/;
Instead, this replaces dog! with donkey., since the dot matches the exclamation mark.
Assuming that the variable contents themselves are not hardcoded, e.g., they can come from a file or from the command line, is there a way to quote or otherwise markdown the contents of a variable so that they are not interpreted as a regular expression in such substitution operations?
Or is there a better way to handle fixed strings? Preferably something that would still allow me to use regex-like features such as anchors or back-references.
Run your $search through quotemeta:
my $text = 'The quick brown fox jumps over the lazy dog!';
my $search = quotemeta('dog.');
my $replace = 'donkey.';
$text =~ s/$search/$replace/;
This will unfortunately not allow you to use other regex features. If you have a select set of features you want to escape out, perhaps you can just run your $search through a first "cleaning" regex or function, something like:
my $search = 'dog.';
$search = clean($search);
sub clean {
my $str = shift;
$str =~ s/\./\\\./g;
return $str;
}
Wrap your search string with \Q...\E, which quotes any meta characters within.
$text =~ s/\Q$search\E/$replace/;
#Replace a string without using RegExp.
sub str_replace {
my $replace_this = shift;
my $with_this = shift;
my $string = shift;
my $length = length($string);
my $target = length($replace_this);
for(my $i=0; $i<$length - $target + 1; $i++) {
if(substr($string,$i,$target) eq $replace_this) {
$string = substr($string,0,$i) . $with_this . substr($string,$i+$target);
return $string; #Comment this if you what a global replace
}
}
return $string;
}