none
поиск файлов без содержания пробелов в имени Regex::Matches RRS feed

  • Вопрос

  • пример скрипта

    $Folder="C:\1\"
    $GetFile=(Get-Childitem $Folder)
    foreach ($File in $GetFile) 
    {
    $File
    $Parsing=[Regex]::Matches($File,'(?<=)*_\w.*?(?=_)\w')-join':' -replace "_" ,""
    $Parsing
    }

    происходит поиск файлов по условию '(?<=)*_\w.*?(?=_)\w' ,то есть файл например с именем 60a_14b_01.txt у меня найдет. Каким образом размещается \S так, чтобы я в ответе  я не видел файлы содержащие пробелы, до второго нижнего подчеркивания

    пример файлов которые я не должен видеть:

    60a_14    b_01

    60    a_14b_01

    спасибо за ответы


    • Изменено last_kpojl 9 мая 2015 г. 9:37

Ответы

  • PS C:\Windows\System32\> Get-ChildItem "C:\temp\te st\"
    
    
        Directory: C:\temp\te st
    
    
    Mode                LastWriteTime     Length Name                                                            
    ----                -------------     ------ ----                                                            
    -a---        09.05.2015     14:20          0 1 2.txt                                                         
    -a---        09.05.2015     14:20          0 1_.txt                                                          
    -a---        09.05.2015     14:21          0 1_2.txt                                                         
    
     

    Что бы получить все не содержащие пробелы достаточно добавить одно условие

    PS C:\> Get-ChildItem "C:\temp\te st\" | where {$_.Name -notlike "* *"}
    
    
        Directory: C:\temp\te st
    
    
    Mode                LastWriteTime     Length Name                                                            
    ----                -------------     ------ ----                                                            
    -a---        09.05.2015     14:20          0 1_.txt                                                          
    -a---        09.05.2015     14:21          0 1_2.txt                                                         

    • Помечено в качестве ответа last_kpojl 10 мая 2015 г. 15:11
    Модератор
  • PS C:\> $Folder="C:\temp\te st\"
    $GetFile=(Get-Childitem $Folder)
    foreach ($File in $GetFile) 
    {
        if ($File -match '^[^_]\w+_\w+_\w+\s*\w*.txt'){
            $Matches.Values
        }
        Else {"----Other file---- $File"}
    }
    
    ----Other file---- New_Text Document.txt
    ----Other file---- text1-text2_text3.txt.txt
    ----Other file---- _text1_text2_text3.txt
    ----Other file---- ча    сть1_часть2_часть3.txt
    ----Other file---- часть1_час    ть2_часть3.txt
    текст1_текст2_текст 3.txt
    часть1_часть2_час    ть3.txt
    часть1_часть2_часть3.txt

    или вот так даже наверное лучше

    $Folder="C:\temp\te st\"
    $GetFile=(Get-Childitem $Folder)
    foreach ($File in $GetFile) 
    {
        if ($File -match '^[^_ ]+_[^ ]+_[\w\s]*.txt'){
            $Matches.Values
        }
        Else {"----Other file---- $File"}
    }

    по результатам тестов 600 объектов обрабатывается за 40 - 50 мсек


    Есть еще один нюанс: \w содержит в себе "_" по сему в 3м блоке возможны варианты "__" или имена файлов в которых есть более 2х"_" (пример: перваячасть123_втораячасть234_3 часть_4!.txt)

    для того что бы оставить только файлы из указанного шаблона можно использовать что то на манер этого:

    '^[^_ ]+_[^_ ]+_(?>[^_]|[\s])*.txt'

    ну и готовый вариант будет выглядеть так

    $Folder="C:\temp\test\"
    $GetFile=(Get-Childitem $Folder)
    foreach ($File in $GetFile) 
    {
        if ($File -match '^[^_ ]+_[^_ ]+_(?>[^_]|[\s])*.txt'){
            $Matches.Values
        }
        Else {"----Other file---- $File"}
    }



    • Изменено Vector BCOModerator 9 мая 2015 г. 22:12
    • Помечено в качестве ответа last_kpojl 10 мая 2015 г. 13:50
    Модератор

Все ответы

  • опишите пример

    Есть файлы "1.txt", "1_.txt", "1 2.txt", "1_2 3.txt", кто из них вам нужен?

    Либо приведите свой пример

    Модератор
  • PS C:\Windows\System32\> Get-ChildItem "C:\temp\te st\"
    
    
        Directory: C:\temp\te st
    
    
    Mode                LastWriteTime     Length Name                                                            
    ----                -------------     ------ ----                                                            
    -a---        09.05.2015     14:20          0 1 2.txt                                                         
    -a---        09.05.2015     14:20          0 1_.txt                                                          
    -a---        09.05.2015     14:21          0 1_2.txt                                                         
    
     

    Что бы получить все не содержащие пробелы достаточно добавить одно условие

    PS C:\> Get-ChildItem "C:\temp\te st\" | where {$_.Name -notlike "* *"}
    
    
        Directory: C:\temp\te st
    
    
    Mode                LastWriteTime     Length Name                                                            
    ----                -------------     ------ ----                                                            
    -a---        09.05.2015     14:20          0 1_.txt                                                          
    -a---        09.05.2015     14:21          0 1_2.txt                                                         

    • Помечено в качестве ответа last_kpojl 10 мая 2015 г. 15:11
    Модератор
  • предложенный ответ не устроит вот почему.мои имена файлов всегда стостоят из трех частей
    часть1_часть2_часть3, где в первой части у меня могут быть любые знаки, числа, Кроме пробелов,затем следуют нижнее подчеркивание,
    во второй части у меня могут быть знаки ,цифры ,кроме пробелов,затем нижнее подчеркивание,
    а уже в третей части может быть все и пробелы в том числе.как мне вот такое условие поиска задать.

    пример имен файлов которые я должен видеть:(исходя из моего условия '(?<=)*_\w.*?(?=_)\w' )

    1.часть1_часть2_часть3.txt
    2.часть1_часть2_час    ть3.txt

    пример имен которых я не должен видеть

    1.ча    сть1_часть2_часть3.txt

    2.часть1_час    ть2_часть3.txt

    причем я выше писал что хотел бы узнать куда правильно поставить \S .

    потому что у меня будут 2 коллекции одна с \s вторая\S.то есть сначала я хочу отсортировать файлы в первых двух частях которые есть пробелы ,затем работать с теми в которых пробелов нет 

     
    • Изменено last_kpojl 9 мая 2015 г. 13:57
  • PS C:\> Get-ChildItem "C:\temp\te st\" 
    
    
        Directory: C:\temp\te st
    
    
    Mode                LastWriteTime     Length Name                                                            
    ----                -------------     ------ ----                                                            
    -a---        09.05.2015     14:21          0 ча    сть1_часть2_часть3.txt                                    
    -a---        09.05.2015     18:39          0 часть1_час    ть2_часть3.txt                                    
    -a---        09.05.2015     14:20          0 часть1_часть2_час    ть3.txt                                    
    -a---        09.05.2015     14:20          0 часть1_часть2_часть3.txt                                        
    


    PS C:\> Get-ChildItem "C:\temp\te st\" | where {(($_.Name -split "_")[0] -notlike "* *") -and (($_.Name -split "_")[1] -notlike "* *")}
    
    
        Directory: C:\temp\te st
    
    
    Mode                LastWriteTime     Length Name                                                            
    ----                -------------     ------ ----                                                            
    -a---        09.05.2015     14:20          0 часть1_часть2_час    ть3.txt                                    
    -a---        09.05.2015     14:20          0 часть1_часть2_часть3.txt                                        

    Регулярные выражения это хорошо но если можно сделать просто лучше сделать просто (ИМХО)

    Если файлов будет больше 10000 (большое число с потолка), можно получить значительное снижение скорости при неправильном использовании regex

    Чуть позже попробую сделать вариант и с регулярными выражениями, но сейчас думать лень

    (может кто то предложит вариант другой)

    Модератор
  • вы все верно говорите.я просто в таком случае не объяснил  полностью свою задачу и это моя вина.
    Существует папка в которую приходит файл от пользователя.суть моего парсинга в том чтобы отфильтровать правильные и неправильные имена.

    в данном приведенном мной примере ваш способ работает,он настолько я понял делит стоку на подстоку и смотрит есть ли в подстроке пробел.
    моя задача подразумевает не совсем то .пользователь по ошибке назвал файл

    text1-text2_text3.txt      (менее одно знака нижнего подчеркивания)

    _text1_text2_text3.txt   (более двух подчеркиваний)

    text 1_text2_text3.txt    (наличие пробела в первой части)

    text1_tex t2_text3.txt    (наличие пробела во второй части)

    text1-text2 - содержат любые знаки цифры и буквы
    text3 - может содержать любые буквы ,цифры ,символы,и содержать пробелы

    если пользователь правильно называет фаил я дальше работаю с этой коллекцией(уже нашел ошибку в своем условии поиска))
    если он назвал его не правильно я переименовываю фаил в исходной папке(уже работаю с другой коллекцией).

    выбран поиск по регулярным выражения по  причинам
    1.задание жестких рамок для поиска
    2.изучение регулярных выражений в принципе
    3.возможность в дальнейшем задавать более гибкие условия для поиска(завтра например пользователю надо будет в "text2" обязательно в середине ставить точку "te.xt2")
    4 максимальное количество файлов 40-100 .время на отработку скрипта 5-10 минут.

    (к сожалению я месяц назад начал изучать PS и немного трудно охватить все)и если я еще справлюсь с заданием условия поиска ,то с условием что в первой и второй части (text1 и xt2)обязательно должны отсутствовать пробелы ,я пока справится не могу



    • Изменено last_kpojl 9 мая 2015 г. 19:06
  • PS C:\> $Folder="C:\temp\te st\"
    $GetFile=(Get-Childitem $Folder)
    foreach ($File in $GetFile) 
    {
        if ($File -match '^[^_]\w+_\w+_\w+\s*\w*.txt'){
            $Matches.Values
        }
        Else {"----Other file---- $File"}
    }
    
    ----Other file---- New_Text Document.txt
    ----Other file---- text1-text2_text3.txt.txt
    ----Other file---- _text1_text2_text3.txt
    ----Other file---- ча    сть1_часть2_часть3.txt
    ----Other file---- часть1_час    ть2_часть3.txt
    текст1_текст2_текст 3.txt
    часть1_часть2_час    ть3.txt
    часть1_часть2_часть3.txt

    или вот так даже наверное лучше

    $Folder="C:\temp\te st\"
    $GetFile=(Get-Childitem $Folder)
    foreach ($File in $GetFile) 
    {
        if ($File -match '^[^_ ]+_[^ ]+_[\w\s]*.txt'){
            $Matches.Values
        }
        Else {"----Other file---- $File"}
    }

    по результатам тестов 600 объектов обрабатывается за 40 - 50 мсек


    Есть еще один нюанс: \w содержит в себе "_" по сему в 3м блоке возможны варианты "__" или имена файлов в которых есть более 2х"_" (пример: перваячасть123_втораячасть234_3 часть_4!.txt)

    для того что бы оставить только файлы из указанного шаблона можно использовать что то на манер этого:

    '^[^_ ]+_[^_ ]+_(?>[^_]|[\s])*.txt'

    ну и готовый вариант будет выглядеть так

    $Folder="C:\temp\test\"
    $GetFile=(Get-Childitem $Folder)
    foreach ($File in $GetFile) 
    {
        if ($File -match '^[^_ ]+_[^_ ]+_(?>[^_]|[\s])*.txt'){
            $Matches.Values
        }
        Else {"----Other file---- $File"}
    }



    • Изменено Vector BCOModerator 9 мая 2015 г. 22:12
    • Помечено в качестве ответа last_kpojl 10 мая 2015 г. 13:50
    Модератор