regex replace
-
mardi 31 janvier 2012 20:52
Hi I'm trying to rename a bunch of file with rename-item. I want to use a regex in conjuction w/ replace but am having some trouble.
files are named:
20110101_2123_8853_NIRNRGB.e1f,
20110223_2556_1482_RGBNRGB.e1f
and i want to rename them
20110101_2123_NIR.e1f,
20110223_2556_RGB.e1f
get-childitem | where-object {$_.name -match "\d{1,4}_[nr][ig][rb]NRGB"}| foreach {Rename-Item -WhatIf $_.name $_.name.replace("\d{1,4}_NIRNRGB","_NIR")}
when I delet the
\d{1,4}
component of the replace parameters it seem to work.. so that tells me that my regex is wrong or not escaped properly. Any insight?
Toutes les réponses
-
mardi 31 janvier 2012 21:07Modérateur
I think you have the Powershell -replace operator confused with the string .replace() method.
The -replace operator uses regex matches. The string method only takes literal text arguments.
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " " -
mardi 31 janvier 2012 23:13I shall contemplate this.. on the tree of woe.
-
mardi 31 janvier 2012 23:22Modérateur
foreach {Rename-Item $_ -newname ($_.name -replace "\d{1,4}_NIRNRGB","_NIR")}
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "- Marqué comme réponse Chewie Mascara mercredi 1 février 2012 01:20
-
mardi 31 janvier 2012 23:31Thanks.. you were correct. I was mixed up. Probably still am a bit...
Now can the -replace operator conquer multiple matches? i.e. something like this:
{Rename-Item $_ -newname ($_.name -replace "\d{1,4}_NIRNRGB","_NIR", "\d{1,4}_RGBNRGB", "_RGB")? I think i'll give it a try -
mardi 31 janvier 2012 23:57Modérateur
It can, but not like that.
'20110101_2123_8853_NIRNRGB.e1f','20110223_2556_1482_RGBNRGB.e1f'| foreach {$_ -replace '\d{1,4}_(NIR|RGB)NRGB','$1'} 20110101_2123_NIR.e1f 20110223_2556_RGB.e1f
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " " -
mercredi 1 février 2012 00:41As an aside, it occurs to me that someone doing this kind of mass renaming will find that powershell makes it easier to avoid a problem common to batch and vbscript, in which already renamed files appear again in the list of files to be renamed.
-
mercredi 1 février 2012 01:33
Thanks for the help. Without taking up too much of your time could you offer some insight into the use of the $1?
Again.. thanks for the help.
-
mercredi 1 février 2012 02:14Modérateur
If the regex matches, the match group contents are available as $n (one for each match group, similar to $matches). $0 will be the entire match string. $1 will be the first captured group, etc. In this case there is only one captured group -(NIR|RGB) - the pipe makes it an alternating match (it will match either NIR or RGB), and whichever one it was will be in $1.
Note that these are NOT Powershell variables - they are created by the regex, and they must be single quoted if you use them in the replacement text argument so that Powershell does not try to evaluate the as Powershell variables.
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " " -
mercredi 1 février 2012 03:42
Excellent bit of info. Thank you.
-
samedi 18 février 2012 14:26
Hey here's a question:If the regex matches, the match group contents are available as $n (one for each match group, similar to $matches). $0 will be the entire match string. $1 will be the first captured group, etc. In this case there is only one captured group -(NIR|RGB) - the pipe makes it an alternating match (it will match either NIR or RGB), and whichever one it was will be in $1.
Note that these are NOT Powershell variables - they are created by the regex, and they must be single quoted if you use them in the replacement text argument so that Powershell does not try to evaluate the as Powershell variables.
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
Why is the first captured group ($1) the -(NIR|RGB)- portion of the regex and not the -\d{1,4}- portion? -
samedi 18 février 2012 14:37Modérateur
Capture groups are defined by the parens. In this example, \d{1,4} is not enclosed in any grouping parens, so it will not be one of the captured groups.
$0 will always be captured, and will always be the entire match - you can't control that. After that, the captured groups will be up to you. Whatever portions of the regex you enclose in parens will become the capture groups from 1 to however many groups you define in the regex. If you want the \d{1,4} to be captured, then use:
foreach {$_ -replace '(\d{1,4})_(NIR|RGB)NRGB','$1'}
and it will become capture group1, and then (NIR|RGB) will become capture group 2.
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
- Marqué comme réponse Chewie Mascara samedi 18 février 2012 15:39
-
samedi 18 février 2012 14:39
Here is the Regex:
'\d{1,4}_(NIR|RGB)NRGB'
There is only one captured group, enclosed in ( ). That's why. If you wanted to capture the part you mention, it will become the first captured group, and the second one will be (NIR|RGB) :
'(\d{1,4})_(NIR|RGB)NRGB'
Grant Ward, a.k.a. Bigteddy
- Marqué comme réponse Chewie Mascara samedi 18 février 2012 15:36
-
samedi 18 février 2012 14:44ModérateurMornin Teddy :-). OT - if you don't add the new V3 OGV -passthru and -output mode parameters to your Wiki pretty soon, I'm going to. They're too good to keep a secret ;-).
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
-
samedi 18 février 2012 15:38
Here is the Regex:
'\d{1,4}_(NIR|RGB)NRGB'
There is only one captured group, enclosed in ( ). That's why. If you wanted to capture the part you mention, it will become the first captured group, and the second one will be (NIR|RGB) :
'(\d{1,4})_(NIR|RGB)NRGB'
Grant Ward, a.k.a. Bigteddy
Thank you kindly for the explanation. I do appreciate the help.
-
samedi 18 février 2012 15:39
Capture groups are defined by the parens. In this example, \d{1,4} is not enclosed in any grouping parens, so it will not be one of the captured groups.
$0 will always be captured, and will always be the entire match - you can't control that. After that, the captured groups will be up to you. Whatever portions of the regex you enclose in parens will become the capture groups from 1 to however many groups you define in the regex. If you want the \d{1,4} to be captured, then use:
foreach {$_ -replace '(\d{1,4})_(NIR|RGB)NRGB','$1'}
and it will become capture group1, and then (NIR|RGB) will become capture group 2.
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
Again, thank you.
-
dimanche 19 février 2012 14:14
Mornin Teddy :-). OT - if you don't add the new V3 OGV -passthru and -output mode parameters to your Wiki pretty soon, I'm going to. They're too good to keep a secret ;-).
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
I can't find good info on these parameters. Perhaps you have experimented with them? I messed about with -Passthru a bit, but it didn't behave as I expected.
Grant Ward, a.k.a. Bigteddy
What's new in Powershell 3.0 (Technet Wiki)
- Modifié BigteddyMicrosoft Community Contributor dimanche 19 février 2012 14:14
-
dimanche 19 février 2012 14:45Modérateur
The documentation isn't very good. From what I've been able to figure out, the -passthru, -wait, and -outputmode parameters are new.
OGV -wait runs OGV and then stops execution until you close the gridview.
-outputmode and -passthru lets you use OGV in the middle of the pipeline as basically a prompted filter.
Pipe a collection to OGV -outputmode single, and it will stop the pipeline, display that collection and let you select one object from the gridview that will continue on down the pipeline when you hit the OK button at the bottom
Use the -outputmode multi option and you can select multiple objects from the gridview to send on down the pipeline, using the normal control and shift convention for selecting multiple entries from a list.
The -passthru switch seems to act just like -outputmode single. I haven't figured out what the difference is there yet.
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
- Modifié mjolinorMicrosoft Community Contributor, Moderator dimanche 19 février 2012 14:46
-
dimanche 19 février 2012 15:53
I like that -outputmode thing. It can, for example, allow you to view all processes, and then drill down to one for more detail:
ps | Out-GridView -OutputMode Single | ps | fl *
Grant Ward, a.k.a. Bigteddy
-
dimanche 19 février 2012 16:05Modérateur
I used both the single and multi options in this add-on I wrote for creating a snippet for splatting cmdlet parameters:
http://mjolinor.wordpress.com/2012/01/16/ps-v3-ise-add-on-for-splatting-updated/
It uses the single option to select the parameter set you want to use, then multi to select the parameters from that set that you want to splat.
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
-
dimanche 19 février 2012 16:20
-
dimanche 19 février 2012 16:26Modérateur
Very good.
I thought it should be added, but also thought it better if the entries all have the same "style", and you get that when the same person is doing the maintenance.
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

