How to filter a folder list looking for files that are in all CAPS?

This topic contains 5 replies, has 3 voices, and was last updated by Profile photo of Bob McCoy Bob McCoy 1 year, 5 months ago.

  • Author
    Posts
  • #28818
    Profile photo of Gavin Williams
    Gavin Williams
    Participant

    Hi,

    I would like to do a get-childitem but set up a regex that says only to select files whose name is in all capitals.

    e.g.
    ERROR.LOG
    OUTPUT.TXT
    FOO.BAR
    but not
    FOO.bar
    error.LOG
    etc.

    Any ideas? many thanks

  • #28820
    Profile photo of Vasken
    Vasken
    Participant

    You can try something like the following, the procedure of which can be described as:

    "Get all child items where the base name and file extension both match a regex that contains the character class [A-Z] (In the case of the second regex, I include a period after the caret character because the Extension property of a Child Item includes the period as the first character in the string.

     Get-Childitem | 
        Where-Object {
            ($_.BaseName -cmatch '^[A-Z]+$') -and 
            ($_.Extension -cmatch '^.[A-Z]+$') }
    

    There are probably shorter ways to get this done, but the key points are using -cmatch instead of -match in order to enforce case sensitivity, and making sure you are checking the correct properties of each child item.

  • #28821
    Profile photo of Bob McCoy
    Bob McCoy
    Participant

    So basically what you really want is file names that don't have lower case letters in them. Here is a snippet using your sample file names.

    $list = @"
    ERROR.LOG
    OUTPUT.TXT
    FOO.BAR
    FOO.bar
    error.LOG
    "@ -split "`r`n"
    $list | foreach {
        if ($_ -cnotmatch "[a-z]")
        {
            "$_"
        }
    }
    

    Or using Get-ChildItem ...

    Get-ChildItem -File | foreach {
        if ($_ -cnotmatch "[a-z]") { "$_" }
    }
    
  • #28823
    Profile photo of Vasken
    Vasken
    Participant

    Good call Bob, it's faster to check for the non-existence of lowercase characters, like in your examples.

    Measure-Command {Get-ChildItem -File | foreach {
        if ($_ -cnotmatch "[a-z]") { "$_" }
    }}
    
    Days              : 0
    Hours             : 0
    Minutes           : 0
    Seconds           : 0
    Milliseconds      : 2
    Ticks             : 28345
    TotalDays         : 3.2806712962963E-08
    TotalHours        : 7.87361111111111E-07
    TotalMinutes      : 4.72416666666667E-05
    TotalSeconds      : 0.0028345
    TotalMilliseconds : 2.8345
    
    Measure-Command {Get-Childitem | 
        Where-Object {
            ($_.BaseName -cmatch '^[A-Z]+$') -and 
            ($_.Extension -cmatch '^.[A-Z]+$') }}
    
    Days              : 0
    Hours             : 0
    Minutes           : 0
    Seconds           : 0
    Milliseconds      : 4
    Ticks             : 43857
    TotalDays         : 5.07604166666667E-08
    TotalHours        : 1.21825E-06
    TotalMinutes      : 7.3095E-05
    TotalSeconds      : 0.0043857
    TotalMilliseconds : 4.3857
    
  • #28879
    Profile photo of Gavin Williams
    Gavin Williams
    Participant

    nice one guys... that's great and it works...
    Quick one... I haven't seen $_ before on its own... versus using $_.xxx. Does this then check across the full contents of the string ?

  • #28881
    Profile photo of Bob McCoy
    Bob McCoy
    Participant

    It all depends on what $_ represents in the pipeline. At all times it means the current object in the pipeline. And that may be a simple string object (as in the case above), an array, a hash table, a multiple-property object (like a file system or process object), or whatever. It's up to you as the scripter to know what $_ represents. To that end, Get-Member is your best friend!

You must be logged in to reply to this topic.