Лучший отвечающий
поиск файлов без содержания пробелов в имени Regex::Matches

Вопрос
-
пример скрипта
$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
9 мая 2015 г. 9:36
Ответы
-
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
9 мая 2015 г. 11:29Модератор -
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
9 мая 2015 г. 20:03Модератор
Все ответы
-
опишите пример
Есть файлы "1.txt", "1_.txt", "1 2.txt", "1_2 3.txt", кто из них вам нужен?
Либо приведите свой пример
9 мая 2015 г. 11:19Модератор -
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
9 мая 2015 г. 11:29Модератор -
предложенный ответ не устроит вот почему.мои имена файлов всегда стостоят из трех частей
часть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
9 мая 2015 г. 13:43 -
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
Чуть позже попробую сделать вариант и с регулярными выражениями, но сейчас думать лень
(может кто то предложит вариант другой)
- Изменено Vector BCOModerator 9 мая 2015 г. 15:48
9 мая 2015 г. 15:44Модератор -
вы все верно говорите.я просто в таком случае не объяснил полностью свою задачу и это моя вина.
Существует папка в которую приходит файл от пользователя.суть моего парсинга в том чтобы отфильтровать правильные и неправильные имена.в данном приведенном мной примере ваш способ работает,он настолько я понял делит стоку на подстоку и смотрит есть ли в подстроке пробел.
моя задача подразумевает не совсем то .пользователь по ошибке назвал файл
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
9 мая 2015 г. 18:57 -
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
9 мая 2015 г. 20:03Модератор