PowerShell читает текстовый файл по строкам и находит отсутствующий файл в папках. Поиск в файле в powershell


PowerShell читает текстовый файл по строкам и находит отсутствующий файл в папках

проверялось, но вот как я бы подойти к нему:

$Location = "I:\\Vendors\\.+\\Invoices\\.+" $txt = "C:\\Users\sbagford.RECOEQUIP\Desktop\AP.txt" $Output ="I:\\Vendors\Missing\Missing.txt" select-string -path $txt -pattern $Location -notMatch | set-content $Output

Нет необходимости выбирать файл по строкам; PowerShell может сделать это для вас, используя select-string. Параметр -notMatch просто инвертирует поиск и отправляет любые строки, которые не соответствуют шаблону.

select-string отправляет поток matchinfo объектов, содержащих строки, которые удовлетворяют условиям поиска. Эти объекты фактически содержат гораздо больше информации, которая соответствует только строке соответствия, но, к счастью, PowerShell достаточно умен, чтобы знать, как отправить соответствующий элемент до set-content.

Регулярные выражения могут быть хитрыми, чтобы получить право, но стоит опустить голову, если вы собираетесь выполнять такие задачи.

EDIT

$Location = "I:\Vendors\{0}\Invoices\{1}.pdf" $txt = "C:\\Users\sbagford.RECOEQUIP\Desktop\AP.txt" $Output = "I:\Vendors\Missing\Missing.txt" get-content -path $txt | % { # extract fields from the line $lineItems = $_ -split " " # construct path based on fields from the line $testPath = $Location -f $lineItems[0], $lineItems[1] # for debugging purposes write-host ("Line:'{0}' Path:'{1}'" -f $_, $testPath) # test for existence of the path; ignore errors if (-not (get-item -path $testPath -ErrorAction SilentlyContinue)) { # path does not exist, so write the line to pipeline write-output $_ } } | Set-Content -Path $Output

Я думаю, мы должны выбрать через файл строку за строкой в ​​конце концов. Если есть более идиоматический способ сделать это, это ускользает от меня.

Приведенный выше код предполагает согласованный формат во входном файле и использует -split, чтобы разбить строку на массив.

EDIT - версия 3

$Location = "I:\Vendors\{0}\Invoices\{1}.pdf" $txt = "C:\\Users\sbagford.RECOEQUIP\Desktop\AP.txt" $Output = "I:\Vendors\Missing\Missing.txt" get-content -path $txt | select-string "(\S+)\s+(\S+)" | %{ # pull vendor and invoice numbers from matchinfo $vendor = $_.matches[0].groups[1] $invoice = $_.matches[0].groups[2] # construct path $testPath = $Location -f $vendor, $invoice # for debugging purposes write-host ("Line:'{0}' Path:'{1}'" -f $_.line, $testPath) # test for existence of the path; ignore errors if (-not (get-item -path $testPath -ErrorAction SilentlyContinue)) { # path does not exist, so write the line to pipeline write-output $_ } } | Set-Content -Path $Output

Казалось, что -split " " вели себя по-разному в запущенном скрипте, как он ведет себя в командной строке. Weird. Во всяком случае, эта версия использует регулярное выражение для синтаксического анализа входной строки. Я протестировал его против данных примера в исходном сообщении, и он, похоже, сработал.

Регулярное выражение разбивается следующим образом

( Start the first matching group \S+ Greedily match one or more non-white-space characters ) End the first matching group \s+ Greedily match one or more white-space characters ( Start the second matching group \S+ Greedily match one or more non-white-space characters ) End the second matching groups

stackoverrun.com

powershell - Как использовать FINDSTR в PowerShell, чтобы найти строки, где все слова в строке поиска совпадают в любом порядке

Вы можете использовать Select-String для поиска на основе регулярного выражения с помощью нескольких файлов.

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

Get-ChildItem -Filter *.abc -Recurse |Select-String -Pattern '^(?=.*\bword1\b)(?=.*\bword2\b)(?=.*\bword3\b).*$'

В приведенном выше примере это то, что происходит с первой командой:

Get-ChildItem -Filter *.abc -Recurse

Get-ChildItem выполняет поиск файлов в текущем каталоге -Filter *.abc показывает нам только файлы, заканчивающиеся на *.abc -Recurse выполняет поиск всех подпапок

Затем мы передаем результирующие объекты FileInfo в Select-String и используем следующий шаблон регулярного выражения:

^(?=.*\bword1\b)(?=.*\bword2\b)(?=.*\bword3\b).*$ ^ # start of string (?= # open positive lookahead assertion containing .* # any number of any characters (like * in wildcard matching) \b # word boundary word1 # the literal string "word1" \b # word boundary ) # close positive lookahead assertion ... # repeat for remaining words .* # any number of any characters $ # end of string

Поскольку каждая группа lookahead только утверждается для правильности, и позиция поиска внутри строки никогда не изменяется, порядок не имеет значения.

Если вы хотите, чтобы он соответствовал строкам, содержащим любое из слов, вы можете использовать простую группу, не связанную с захватом:

Get-ChildItem -Filter *.abc -Recurse |Select-String -Pattern '\b(?:word1|word2|word3)\b' \b(?:word1|word2|word3)\b \b # start of string (?: # open non-capturing group word1 # the literal string "word1" | # or word2 # the literal string "word2" | # or word3 # the literal string "word3" ) # close positive lookahead assertion \b # end of string

Это, конечно, можно отвлечь в простую функцию прокси.

Я сгенерировал блок param и большую часть тела определения функции Select-Match ниже:

$slsmeta = [System.Management.Automation.CommandMetadata]::new((Get-Command Select-String)) [System.Management.Automation.ProxyCommand]::Create($slsmeta)

Затем удалены ненужные параметры (включая -AllMatches и -Pattern), затем добавлен генератор шаблонов (см. встроенные комментарии):

function Select-Match { [CmdletBinding(DefaultParameterSetName='Any', HelpUri='http://go.microsoft.com/fwlink/?LinkID=113388')] param( [Parameter(Mandatory=$true, Position=0)] [string[]] ${Substring}, [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)] [Alias('PSPath')] [string[]] ${LiteralPath}, [Parameter(ParameterSetName='Any')] [switch] ${Any}, [Parameter(ParameterSetName='Any')] [switch] ${All}, [switch] ${CaseSensitive}, [switch] ${NotMatch}, [ValidateNotNullOrEmpty()] [ValidateSet('unicode','utf7','utf8','utf32','ascii','bigendianunicode','default','oem')] [string] ${Encoding}, [ValidateNotNullOrEmpty()] [ValidateCount(1, 2)] [ValidateRange(0, 2147483647)] [int[]] ${Context} ) begin { try { $outBuffer = $null if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) { $PSBoundParameters['OutBuffer'] = 1 } # Escape literal input strings $EscapedStrings = foreach($term in $PSBoundParameters['Substring']){ [regex]::Escape($term) } # Construct pattern based on whether -Any or -All was specified if($PSCmdlet.ParameterSetName -eq 'Any'){ $Pattern = '\b(?:{0})\b' -f ($EscapedStrings -join '|') } else { $Clauses = foreach($EscapedString in $EscapedStrings){ '(?=.*\b{0}\b)' -f $_ } $Pattern = '^{0}.*$' -f ($Clauses -join '') } # Remove the Substring parameter argument from PSBoundParameters $PSBoundParameters.Remove('Substring') |Out-Null # Add the Pattern parameter argument $PSBoundParameters['Pattern'] = $Pattern $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Utility\Select-String', [System.Management.Automation.CommandTypes]::Cmdlet) $scriptCmd = {& $wrappedCmd @PSBoundParameters } $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin) $steppablePipeline.Begin($PSCmdlet) } catch { throw } } process { try { $steppablePipeline.Process($_) } catch { throw } } end { try { $steppablePipeline.End() } catch { throw } } <# .ForwardHelpTargetName Microsoft.PowerShell.Utility\Select-String .ForwardHelpCategory Cmdlet #> }

Теперь вы можете использовать его так, и он будет вести себя примерно как Select-String:

Get-ChildItem -Filter *.abc -Recurse |Select-Match word1,word2,word3 -All

qaru.site

powershell - PowerShell: поиск части строки в файле журнала

Я бы ожидал, что $ match всегда будет нулевым. Согласно справке, Out-File никогда ничего не отправляет по трубопроводу. Но я был бы удивлен, если бы это было связано с вашей проблемой.

В духе "Любая помощь будет высоко оценена"...

Я попробовал простой эксперимент как на Win7, так и на WS08R2 и не смог воспроизвести результаты (он работал, как ожидалось). Я также попытался создать поиск файла с различными кодировками: Unicode, UTF8 и ASCII. Все работало. Я даже сказал Select-String, чтобы использовать неправильную кодировку:

get-content mytestfile.ascii | select-string error -Encoding Unicode

и он все еще работал. Я использовал шестнадцатеричный просмотрщик для проверки того, что mytestfile.ascii, mytestfile.unicode и mytestfile.utf8 были на самом деле закодированы по-разному. Я также пробовал разные окончания строк (стиль Linux и стиль Windows), и это сработало.

Я предполагаю, что у вас есть что-то уникальное в отношении файлов, системы и т.д., Которые должны быть обнаружены с помощью некоторого исследования. С этим в мыслях...

Я предлагаю вам заглянуть внутрь одного из ваших файлов журналов с помощью шестнадцатеричного просмотра (попробуйте использовать его из обеих систем), чтобы узнать, не отличается ли ваша система Win7 от вашей системы WS08R2. В начале файла UTF8 вы увидите EF BB BF, а затем один байт для каждого символа вашего журнала. В начале файла Unicode вы увидите FF FE, а затем два байта для каждого символа. (Если текст является английским, то каждый другой символ будет 0). А для файла ASCII в начале нет специального значения, и для каждой буквы есть один байт. Окончания строк в Linux - это один вывод 0A (linefeed) и окончания строки Windows: 0D 0A (возврат каретки, перевод строки). Помимо специальных символов в начале, как упоминалось выше, и окончаний строк, вы должны искать текст точно таким же набором символов, как если бы вы просмотрели его в блокноте. (Кстати, просмотр его в блокноте будет выглядеть только "правильно", если окончание строк - это стиль Windows). Если вы видите какие-то дополнительные символы, то это может быть источником проблемы

Если это не показало ничего неожиданного, я предлагаю серию экспериментов из командной строки Powershell. Следующая процедура содержит много шагов, но она пытается покрыть множество непредвиденных ситуаций. Вы не будете выполнять каждый шаг. (Однако с несколькими модификациями в начале - для учета того, где "ошибка" появляется в файле журнала, который вы используете для тестирования, - вы можете скопировать и вставить весь этот скрипт, а затем интерпретировать весь набор результатов за один раз)

# 0. Get some text to experiment with # If "error" appears on line 200 and line 493 (where first line in file is Line 1), then: $testTxt= cat mylogfile | select-object -skip 195 -first 300 # or better still: $testTxt= cat mylogfile | select-object -skip 195 -first 10 $testTxt2= cat mylogfile | select-object -skip 488 -first 10 $testTxt += $testTxt # 1. Figure out where in testTxt "error" appears $testTxt[3..5] # if my math is right "error" will appear as middle line # 2. If #1 doesn't work on both systems, then on failing system(s): $testTxt[4] | select-string error # 2.5 If #2 fails then you need to look at every character # of $testTxt [char[]]$testTxt # or even look at every byte value in hex: [byte[]][char[]]$textTxt | % { $_.tostring("X")} # 3. If #2 worked, then: $testTxt | select-string error # 4. If #3 failed, then: $testTxt[3..5] | select-string error # 5. If #4 failed, then: $testTxt[3..4] | select-string error $testTxt[4..5] | select-string error # 6. If either of #5 failed, then carefully examine those lines of text: "line 3" [char[]]$testTxt[3] "line 4" [char[]]$testTxt[4] "line 5" [char[]]$testTxt[5] # 7. If #3 worked then: $testTxt2 = cat myLogFile $testTxt2 | select-string error # 8. If #7 worked, then you have a solution # Replace: get-content $file | Select-String $p | Out-File $matchfile # With (on Powershell v3 this may perform worse than the above, assuming above worked) $logText = get-content $file $logText | Select-String $p | Out-File $matchfile # 9. If #8 failed, then the situation is somewhat awkward. # On one hand you have twenty lines working, but on the other the file as a whole # doesn't work. You could go back to step #0 and start with a larger amount of text, # say 40 lines, and see if it works. If it does you could try 80, 160, etc. until it # fails. But this case seems pretty unlikely. # 10. In general when a step fails you want to try something "smaller". And when steps # succeed you want to try something "bigger", where "bigger" means more like the # solution you want.

qaru.site

Работа с файлами при помощи команд PowerShell | Windows IT Pro/RE

Windows PowerShell предоставляет пользователям четыре способа работы с файлами.

  • Применение составных команд. Существует ряд команд, созданных специально для работы с файлами. При помощи этих команд вы можете управлять файлами и путями к файлам так, как если бы работали с содержанием файлов.
  • Применение команд DOS. PowerShell полностью совместим с командами DOS. Таким образом, то, что вы можете сделать при использовании DOS, вы можете сделать и при помощи PowerShell. PowerShell признает даже команду xcopy.
  • Использование инструментария управления Windows Management Instrumentation (WMI). WMI предлагает иной механизм для управления файлами (например, изменение файловых свойств, поиск или переименование файла). Лучше всего запускать команды WMI в удаленном режиме.
  • Применение методов Microsoft. NET Framework. Пространство имен. NET System.IO доступно через командную строку PowerShell. Эта строка включает в себя классы System.IO.File и System.IO.FileInfo.

В данной статье я расскажу о командах, которые были созданы специально для файлов. Вот те команды, которые вы можете использовать для работы с файлами:

Get-ChildItem Get-Item Copy-Item Move-Item New-Item Remove-Item Rename-Item

Использование Get-ChildItem

Команда Get-ChildItem возвращает элементы, обнаруженные в одном или нескольких указанных местах. Местоположение может быть контейнером файловой системы, таким как каталог, или местом, показанным другим провайдером, таким как подраздел реестра или хранилище сертификатов. Вы можете задействовать параметр Recurse данной команды, чтобы добраться до элементов во всех подпапках.

Если использовать эту команду без параметров, она возвращает все дочерние элементы (такие как подпапки и файлы) в текущем местоположении. Например, если текущее местоположение – корневой каталог H, то запуская команду Get-ChildItem, вы получите результаты, похожие на те, что показаны на экране 1.

 

Экран 1. Результаты работы Get-ChildItem

Используя параметры, вы можете получить информацию, которая вам нужна. Например, следующая команда возвращает все файлы. log в корневом каталоге C, включая подкаталоги:

Get-ChildItem C:\* -Include *.log -Recurse -Force

Как мы видим, эта команда использует параметры -Include, -Recurse и –Force. Параметр –Include служит для возвращения заданных элементов. Он поддерживает использование групповых символов и является идеальным для указания расширения имени файла. Параметр –Recurse дает PowerShell указание возвращать подпапки наряду с файлами. Параметр –Force добавляет скрытые и системные файлы к выходным данным.

После запуска этой команды вы, вероятно, получите обширный список сообщений об ошибках доступа. В зависимости от настроек и политик безопасности системы, доступ к некоторым каталогам (например, Recycle Bin, Start Menu, пользовательские папки) ограничен и их нельзя прочитать. Вы можете скрыть эти сообщения об ошибках, указав параметр -ErrorAction SilentlyContinue.

Следующая команда дает те же результаты, что и предыдущая, потому что параметр –Path понимает групповые символы:

Get-ChildItem -Path C:\*.log -Recurse -Force

Для некоторых параметров команд PowerShell имя параметра вы можете опустить, если знаете, что параметр находится в той позиции, которая нужна PowerShell. Так происходит при использовании параметра –Path команды Get-ChildItem. Таким образом, следующая команда выдаст тот же результат, что и предыдущая команда:

Get-ChildItem C:\*.log -Recurse -Force

Параметр –Path может принимать множественные аргументы, разделенные запятыми. Например, предположим, что вы хотите возвратить. log-файлы из двух мест: корневого каталога С и корневого каталога Н, последний является текущим (то есть местоположением по умолчанию). Для выполнения этого действия нужно указать значение C:\* для получения всех файлов журналов из корневого каталога С и значение * для получения всех файлов журналов из корневого каталога Н (поскольку корневая папка Н является местоположением по умолчанию, вам не нужно указывать H:\.). Необходимо разделить два аргумента запятой, например так:

Get-ChildItem C:\*, * -Include *.log -Force

В результатах примера на экране 2 обратите внимание на атрибут «h" в колонке Mode корневого каталога Н. Этот атрибут показывает, что файл ntuser.dat.LOG является скрытым. Это обнаруживается при помощи параметра –Force.

 

Экран 2. Вывод скрытых файлов

Хотя в примерах это и не показано, вы можете обратиться к Get-ChildItem при помощи дополнительных имен, псевдонимов. Вот три встроенных псевдонима: dir (как в DOS команда dir), gci и ls (как команда ls в UNIX).

Использование команды Get-Item

Команда Get-Item возвращает заданные элементы из назначенных местоположений. Как и ChildItem, Get-Item может применяться для навигации по различным типам хранилищ данных. В отличие от Get-ChildItem, Get-Item не имеет местоположения по умолчанию, поэтому вы должны всегда предоставлять, как минимум, одно местоположение с помощью параметра –Path. Хотя сам параметр и нужен, указывать имя параметра не требуется. Например, вот простая команда, которая использует «точку» для возвращения информации о текущем каталоге (в данном случае корневая папка Н):

Get-Item.

Результаты показаны на экране 3. Команда Get-Item позволяет задействовать групповой символ * для возвращения всего содержимого элемента (то есть всех дочерних элементов). Например, следующая команда возвращает весь контент текущего каталога (в данном случае корневого каталога Н). Точка и символ звездочки могут быть использованы как компоненты в пути файла, но вы должны еще указать косую черту как разделитель папок:

Get-Item. \*

 

Экран 3. Использование Get-Item для вывода информации о текущей папке

Результаты вы можете увидеть на экране 4. Важно понимать, что команды PowerShell, включая Get-Item, возвращают объекты. Команда Get-Item возвращает объекты System.IO.DirectoryInfo, которые содержат несколько методов и свойств, которые вы можете использовать. Чтобы увидеть эти методы и свойства, можно передать результаты команды Get-Item в команду Get-Member. Если вы хотите увидеть эти свойства, можете запустить такую команду:

Get-Item. | Get-Member -MemberType Property

 

Экран 4. Использование Get-Item для вывода всего содержимого текущей папки

Как показано на экране 5, свойство LastAccessTime возвращает дату и время, когда к указанному каталогу был в последний раз осуществлен доступ.

 

Экран 5. Изучение свойств объекта System.IO.DirectoryInfo

Например, если вы хотите выяснить, когда к текущему каталогу был осуществлен доступ в последний раз, вы запускаете команду:

(Get-Item. ).LastAccessTime

Заметим, что в этой команде вызов Get-Item. заключен в круглые скобки и что между закрывающей круглой скобкой и LastAccessTime стоит точка. Круглые скобки вокруг вызова «Get-Item. » нужны для того, чтобы возвращенные объекты сохранялись в памяти и вы могли бы выполнять с ними дополнительные операции. В этом случае операцией является поиск возвращаемого значения свойства LastAccessTime объекта. В PowerShell вы используете символ точки для получения доступа к ряду свойств объекта и методов. Вот почему следует вставить точку между закрывающейся скобкой и LastAccessTime.

Существует коллекция специальных свойств, которая называется NoteProperty. Вы можете применять ее для того, чтобы сузить выводимые результаты для определенного типа объекта. Вы можете использовать Get-Member с параметром -MemberType NoteProperty, чтобы узнать о специальных свойствах этой коллекции:

Get-Item. | Get-Member -MemberType NoteProperty

Если вы запустите эту команду, то обнаружите, что коллекция возвращает шесть свойств: PSChildName, PSDrive, PSIsContainer, PSParentPath, PSPath и PSProvider. Свойство PSIsContainer коллекции NoteProperty показывает, является ли объект контейнером (папкой). Свойство возвращает True, когда объект является папкой, и False, когда он является файлом. Вы можете использовать это свойство для ограничения вывода Get-Item папками:

Get-Item C:\* | Where-Object { $_.PSIsContainer }

Давайте обсудим эту команду подробнее. Ее результаты показаны на экране 6. Вы передаете по конвейеру весь контент корневого каталога С команде Where-Object, которая позволяет отфильтровать объекты. В этом случае вы используете PSIsContainer из NoteProperty для фильтрации выходных данных, и, таким образом, возвращаются только каталоги. Автоматическая переменная $_ представляет каждый файловый объект, как только он передается команде по конвейеру.

 

Экран 6. Ограничение вывода команды Get-Item только папками

Как и в случае с Get-ChildItem, вы можете обращаться к Get-Item по дополнительному имени. У Get-Item есть одно встроенное дополнительное имя: gi.

Использование Copy-Item

Команда Copy-Item является реализацией в PowerShell команды copy bp DOS и команды cp из UNIX. Но помимо этого, Copy-Item сконструирован для работы с данными, выдаваемыми любым провайдером. Первыми двумя параметрами команды являются -Path (вы используете его для указания элемента, который хотите скопировать) и –Destination (вы применяете его для указания места, в которое хотите скопировать этот элемент). Они позиционные, поэтому имена параметров можно опустить. Например, следующая команда копирует файл test.txt из папки C:\Scripts в папку C:\Backups\Scripts:

Copy-Item C:\Scripts\test.txt C:\Backups\Scripts

Параметр –Path принимает групповые символы, поэтому вы можете копировать несколько файлов сразу. Например, следующая команда копирует все файлы в папке C:\Scripts в папку C:\Backups\Scripts:

Copy-Item C:\Scripts\* C:\Backups\Scripts

Чтобы получить более детальное управление операцией копирования, вы можете задействовать параметры -Recurse, -Filter и –Force. Так, следующая команда копирует все файлы. txt, содержащиеся в C:\Scripts в C:\Temp\Text:

Copy-Item -Path C:\Scripts -Filter *.txt -Recurse ` -Destination C:\Temp\Text

Обратите внимание, что «обратная кавычка» в конце первой строки является символом продолжения строки в PowerShell.

Немного освоившись, вы можете вставить свойство FullName в параметр –Path для копирования тщательно отобранного списка файловых объектов, используя либо Get-Item, либо команду Get-ChildItem:

Get-ChildItem C:\* -include *.txt | Where-Object { $_.PSIsContainer -eq $false -and ` $_.LastAccessTime -gt ($(Get-Date).AddMonths(-1))} | ForEach-Object { Copy-Item $_.FullName C:\Temp}

На самом деле это предложение является комбинацией трех отдельных команд. Первая команда (то есть команда в первой строке) возвращает все файлы. txt в корневом каталоге С. Вторая команда (команда во второй и третьей строках) вычленяет список текстовых файлов таким образом, что содержит только те файловые объекты, чье свойство LastAccessTime больше, чем месяц назад. Третья команда (команда в последней строке) вставляет каждое файловое имя в свойство –Path, располагающееся в Copy-Item, используя команду ForEach-Object. Слишком сложно для вас? Тогда можете принять входные данные по конвейеру. Только убедитесь, что вы указали имя параметра –Destination так, чтобы Copy-Item знала, что делать с этими входными данными, так как данный параметр находится не в ожидаемой позиции:

Get-ChildItem C:\* -Include *.log | Copy-Item -Destination C:\Temp

Хотя в наших примерах это и не показано, вы можете обратиться к Copy-Item через дополнительные имена. Существует три псевдонима: copy, cp, cpi.

Использование Move-Item

Move-Item очень похожа на Copy-Item. Фактически, если вы заменяете Copy-Item на Move-Item в любой из команд, представленных в предыдущем разделе, команды будут вести себя во многом так же, за исключением того, что исходные файлы будут удалены в исходную папку.

Однако есть одно важное различие. Если вы запустите одну и ту же команду Copy-Item дважды, то обнаружите, что PowerShell переписывает существующий файл в папку назначения без какого-либо предупреждения.

Move-Item более осторожна в этом смысле и вместо удаления выдает ошибку. Например, если вы запускаете команду

Get-ChildItem C:\* -Include *.txt | Where-Object ` { $_.LastAccessTime -gt ($(Get-Date).AddMonths(-1))} | ForEach-Object { Move-Item $_.FullName C:\Temp}

то получите ошибку Cannot create a file («нельзя создать файл»), так как файл уже существует. Использование параметра –Force приводит к тому, что Move-Item переписывает существующий файл.

Помимо параметра –Force, вы можете задействовать параметры Recurse и –Filter в команде Move-Item, чтобы настраивать ее. Например, следующая команда перемещает текстовые файлы в папке C:\Scripts и ее подпапках в папку C:\Temp\Text. В данном случае вам нужно указать имя параметра –Destination, поскольку вы не используете этот параметр в той позиции, где его ожидает PowerShell:

Move-Item C:\Scripts -Filter *.txt -Recurse ` -Destination C:\Temp\Text

Как и Copy-Item, Move-Item имеет три псевдонима: move, mv и mi.

Использование New-Item

New-Item играет двойную роль — создателя каталога и файла (кроме того, она может создавать разделы и параметры реестра). Когда вы хотите создать файл, вам нужно указать параметры –Path и –ItemType. Как было показано выше, параметр –Path является позиционным, таким образом, не требуется имя параметра –Path, когда вы задаете путь и имя (то есть путь к файлу) сразу же после имени команды. Также следует указать параметр –ItemType при помощи флажка»file«. Вот пример:

New-Item 'C:\Documents and Settings\Nate\file.txt' ` -ItemType»file«

Параметр –Path может принимать массив строк так, что вы можете создавать несколько файлов за раз. Вам просто нужно разделить пути при помощи запятых. Вдобавок, необходимо вставить сначала параметр -ItemType»file«, который означает, что вам нужно указать имя параметра –Path, поскольку он теперь не первый параметр после имени команды:

New-Item -ItemType»file«-Path»C:\Temp\test.txt«, ` »C:\Documents and Settings\Nate\file.txt«, ` »C:\Test\Logs\test.log«

Если файл с точно таким же именем пути файла уже существует, вы получите ошибку. Однако вы можете указать параметр –Force так, что New-Item перепишет существующий файл.

Что на самом деле примечательно, так это то, что New-Item позволяет вставлять текст в файл посредством параметра –Value:

New-Item 'C:\Documents and Settings\Nate\file.txt' ` -ItemType»file«-Force ` -Value»Here is some text for my new file.«

Не забудьте указать параметр –Force, если файл уже существует. Иначе система выдаст ошибку.

Параметр –Value может принимать ввод данных по конвейеру, что является отличным способом перенаправлять вывод данных других команд в файл. Вам нужно просто конвертировать выходные объекты в строку, используя Out-String (если вы этого не сделаете, New-Item создаст новый файл для каждого объекта). Например, следующая команда возвращает информацию обо всех файлах из корневого каталога С, конвертирует информацию о файлах в строку, а затем пишет эту информацию в файл H:\C Listing.txt:

Get-ChildItem C:\* | Out-String | New-Item -Path»H:\C Listing.txt«-ItemType»file«-Force

New-Item имеет только одно встроенное дополнительное имя: ni.

Использование Remove-Item

Remove-Item навсегда удаляет ресурс с указанного диска, то есть она не перемещает его в корзину. Таким образом, если вы используете Remove-Item для удаления файла, то нет иного способа вернуть его, кроме как через программу восстановления файлов.

Вы указываете, какой файл должна удалять Remove-Item при помощи параметра –Path. Он позиционный, поэтому вам не нужно указывать имя параметра –Path, если оно идет сразу же за именем команды. Например, вот команда для удаления файла test.txt, который был ранее скопирован в папку C:\Backups\Scripts:

Remove-Item»C:\Backups\Scripts\test.txt«

Давайте рассмотрим другой пример. Следующая команда удаляет все файлы. txt (что указано в параметре –Include) в папке C:\Scripts, кроме тех файлов, которые имеют слово test где-либо в файловом имени (что указано в параметре –Exclude):

Remove-Item C:\Scripts\* -Include *.txt -Exclude *test*

Будучи, по сути, опасным инструментом, Remove-Item предоставляется с парой элементов защиты. Прежде всего, если вы пытаетесь удалить все из папки, которая содержит непустые подпапки, вы получите запрос на подтверждение Confirm. Например, предположим, что C:\Scripts содержит непустые подпапки и вы запускаете такую команду:

Remove-Item C:\Scripts\*

Нужно подтвердить, что вы хотите удалить непустые подпапки, как показано на экране 7.

 

Экран 7. Запрос на подтверждение удаления при использовании Remove-Item

Если вы хотите запустить сценарий, который использует Remove-Itemм для удаления всего содержимого папок, включая содержимое подпапок, вам нужен способ запускать Remove-Item без участия пользователя. Этот способ – включение флажка –Recurse.

Второй элемент защиты – это параметр –WhatIf. Если вы включаете его в команду Remove-Item, то PowerShell покажет, какие элементы будут удалены, вместо того, чтобы просто удалить их. В силу деструктивной природы операций удаления, имеет смысл выполнять пробное применение команды Remove-Item с параметром –WhatIf, как здесь:

Remove-Item c:\* -Recurse -WhatIf

Результаты примера показаны на экране 8. Заметьте, что результаты могут включать в строку сообщение об ошибке Cannot remove the item at 'C:\Users' because it is in use. Такая ситуация возникает, если текущая рабочая папка является подпапкой каталога, которую вы пытаетесь удалить (в примере – подпапка корневого каталога С).

 

Экран 8. Применение Remove-Item с параметром -WhatIf Parameter

Что касается дополнительных имен, то Remove-Item стоит особняком. У него шесть псевдонимов: del, erase, rd, ri, rm и rmdir.

Использование Rename-Item

Команда Rename-Item используется, когда вы хотите переименовать ресурс внутри пространства имен, предоставленного провайдером PowerShell. Первый параметр Rename-Item – это –Path, а второй параметр -NewName. Параметр –NewName, как и следовало ожидать, задает новое имя ресурса. Если Rename-Item обнаруживает не только имя, но и путь, он выдаст ошибку. Например, если вы хотите сменить имя файла C Listing.txt из корневого каталога Н на имя c_listing.txt, вам потребуется запустить такую команду:

Rename-Item -Path»H:\C Listing.txt«-NewName c_listing.txt

Поскольку -Path и -NewName являются позиционными параметрами, вы можете пропускать имена параметров до тех пор, пока они находятся в ожидаемых позициях:

Rename-Item»H:\C Listing.txt" c_listing.txt

У Rename-Item есть одно ограничение – параметр –NewName ожидает одной строки без групповых символов. Однако вы можете обойти это требование, перечисляя элементы в каталоге. Вам нужно просто направить по конвейеру выходные данные команде Get-ChildItem в параметр –Path и указать параметр –NewName.

Например, следующая команда перечисляет все файлы в текущем каталоге и переименовывает каждый файл, заменяя все пробелы в файловых именах на подчеркивания:

Get-ChildItem * | Where-Object {! $_.PSIsContainer } | Rename-Item -NewName { $_.name -replace ' ','_' }

Давайте посмотрим, как работает эта команда. Выходные данные Get-ChildItem попадают в Where-Object, которая фильтрует выходные данные так, что возвращаются только файлы. Это достигается путем использования PSIsContainer из NoteProperty с логическим оператором -not (!) (в качестве альтернативы вы могли бы взять $_.PSIsContainer -eq $false, как это было сделано в предыдущем примере). Отфильтрованные выходные данные (файловые объекты) попадают в Rename-Item. Значение параметра –NewName в Rename-Item является блоком сценария. Этот блок будет выполнен перед командой Rename-Item. В блоке сценария автоматическая переменная $_ представляет каждый файловый объект, так как он попадает в команду через контейнер. Оператор сравнения –replace заменяет пробелы в каждом имени файла (' ') на символ подчеркивания ('_'). Заметьте, что вы можете использовать выражение '\s' для указания пробела, поскольку первый параметр принимает регулярные выражения. Даже скрытые файлы могут быть переименованы благодаря параметру –Force.

Rename-Item имеет два псевдонима: ren и rni.

Великолепная семерка

В данном руководстве я познакомил вас со способами взаимодействия PowerShell с файлами. В частности, мы изучили встроенные команды PowerShell, предназначенные для работы с файлами. Это Get-ChildItem, Get-Item, Copy-Item, Move-Item, New-Item, Remove-Item и Rename-Item.

www.osp.ru

поиск данных в файлах * .txt для экспорта в * .csv

Прежде всего, это мой первый вопрос здесь. Я часто прихожу сюда, чтобы просматривать существующие темы, но теперь я висел на моей собственной проблеме. И я не нашел полезный ресурс прямо сейчас. Моя самая большая проблема заключалась в том, что она не будет работать в Powershell ... На данный момент я пытаюсь получить небольшой инструмент Powershell, чтобы сэкономить мне много времени. Для тех, кто не знает cw-sysinfo, это инструмент, который собирает информацию о любой хост-системе (например, Hardware-ID, Product Key и т. Д.) И генерирует файлы * .txt. Могу сказать, что если у вас есть 20, 30 или 80 серверов в проекте, огромное количество времени для просмотра всех файлов и просто искать нужные вам строки и объединить их в файл * .csv.

Что у меня есть больше похоже на основное средство, оно просматривает все * .txt по определенному пути и проверяет мои ключевые слова. И вот проблема, что я просто не могу использовать слова перед тем, мне действительно нужно, видел, как следующие:

Operating System: Windows XP Product Type: Professional Service Pack: Service Pack 3 ...

Я не знаю, как я могу сказать Powershell искать «Тип продукта:» - линия и выберите вместо этого «Профессионал». Позже с ключами или серийными номерами будет та же проблема, поэтому я просто не могу просматривать «Стандарт» или «Профессионал».

Я поместил свои ключевые слова ($ controls) в дополнительный файл, чтобы я мог прикреплять папки проекта и не нужно редактировать в Powershell каждый раз. Код выглядит следующим образом:

Function getStringMatch { # Loop through the project directory Foreach ($file In $files) { # Check all keywords ForEach ($control In $controls) { $result = Get-Content $file.FullName | Select-String $control -quiet -casesensitive If ($result -eq $True) { $match = $file.FullName # Write the filename according to the entry "Found : $control in: $match" | Out-File $output -Append } } } } getStringMatch

stackoverrun.com

powershell - Powershell - Странный вывод при использовании Get-ChildItem для поиска в файлах

Причина, по которой вы видите это, состоит в том, что $ output представляет собой массив объектов Selected.Microsoft.PowerShell.Commands.GroupInfo - объекты, возвращенные объектом Group-Object при передаче в Select-Object (без Select-Object они просто будут Microsoft.PowerShell.Commands.GroupInfo). Вы можете подтвердить тип объектов в $ ouput, выполнив:

$output | Get-Member

Проверьте TypeName, которое отображается в верхней части вывода.

Когда вы запускаете эти команды интерактивно в консоли, вы видите пути, потому что PowerShell знает, как отображать объекты GroupInfo в консоли, чтобы они были удобными для человека. Обратите внимание, что когда вы просто вызываете $ output в консоли, вы видите заголовок "Name", подчеркнутый символами тире - это PowerShell, интерпретирующий объект GroupInfo, который вы ему дали, и отображающий свойство Name для вас в консоли.

Проблема возникает, когда вы пытаетесь вывести массив $ output внутри строки. Затем PowerShell не может использовать свою более совершенную логику форматирования и вместо этого просто пытается преобразовать объект в строку для вставки в вашу строку. Когда это происходит, у него недостаточно логики, чтобы знать, что то, что вы действительно хотите отобразить в своей строке, - это свойство Name этих объектов GroupInfo, поэтому вместо этого вывести строку с типом имени каждого из объектов в массиве $ output. Итак, почему вы видите имя типа дважды.

Простым решением этой проблемы является параметр -ExpandProperty для Select-Object. Это делает то, что он говорит - он расширяет свойство, которое вы просили, с помощью Select-Object и возвращает только это свойство, а не родительский объект. Таким образом, свойство Name объекта GroupInfo является строкой. Если вы вызываете Select-Object Name, вы получаете объект GroupInfo с свойством Name. Если вы вызываете Select-Object -ExpandProperty Name, вы получаете только свойство Name как объект String. Это то, чего я ожидаю от вас в этом случае.

Поэтому попробуйте это вместо этого:

$output = Get-ChildItem -path $target -recurse | Select-String -pattern hello | group path | select -ExpandProperty name

qaru.site

powershell поиск содержимого текстового файла очень медленнее?

## Create new text file based on the date of today #mu2_20140429040401 $mu = "c:\temp\test\mu2_" $tag = "c:\temp\test\tag_" $Date = Get-Date $DateStr = $Date.ToString("yyyyMMddhhmm") $fname_mu = $mu + $DateStr + "01.txt" $fname_tag = $tag + $DateStr + "01.txt" $src = "c:\temp\test\mt_point.txt" $dstDir = "C:\temp\test\test\" $Location = "C:\temp\test\CompositeID.txt" # Delete previous output files Remove-Item -Path "$dstDir\*"# $inData =New-Object -TypeName System.IO.StreamReader -ArgumentList $src $header = $inData.ReadLine() $header1=$inData.ReadLine() $header2=$inData.ReadLine() $header3=$inData.ReadLine() $header4=$inData.ReadLine() $header5=$inData.ReadLine() $header6=$inData.ReadLine() $header7=$inData.ReadLine() $header8=$inData.ReadLine() $header9=$inData.ReadLine() $header10=$inData.ReadLine() $header11=$inData.ReadLine() $header12=$inData.ReadLine() $header13=$inData.ReadLine() $header14=$inData.ReadLine() $header15=$inData.ReadLine() $currentFile = "" while ($line = $inData.ReadLine()) { #echo $line $s_point =$line -split "," #echo $newFile $s_point=$s_point -replace '''' $point_ID=$s_point[2]+"."+$s_point[3]+"."+$s_point[4]+"."+$s_point[5] #echo $point_ID $Sel = Select-String -pattern $point_ID -path $Location #echo $Sel $tp_point_stirng= $Sel-split ";" $tp_point_no=$tp_point_stirng[0]-split ":" $tp_point=$tp_point_no[3]-split "," if($point_ID -eq $tp_point_stirng[1]) { if($s_point[6]-eq "T") { $Nis_point="!1!"+$tp_point[1]+"!"+$s_point[2]+ "!"+$tp_point_stirng[7]+"!0!SI!!"+$s_point[7]+"!!!!"+ $s_point[8]+"!" # $Nis_point | out-file -filepath $fname_tag -Append # $stream =New-Object System.IO.StreamWriter ($fname_tag,"True",[System.Text.Encoding]::Ascii) # $stream.WriteLine($Nis_point) # $stream.close() } } }

использование «Select-String -pattern $ point_ID -path $ Location» очень медленное, есть ли у вас текстовый файл для поиска в powershell быстрее?

пример:

a.text файл

3,44545; apa.ftp.dfv.de; fdfd; ааа; й;

2,45433; bb.tt.uu.cc; dddd; wwww; tt;

поиск объекта линии - apa.ftp.dfv.de, если соответствие затем выводит строку;

3,44545; apa.ftp.dfv.de; fdfd; aaa; ee;

stackoverrun.com