Powershell удалить строку из файла
Windows PowerShell предоставляет пользователям четыре способа работы с файлами. В данной статье речь пойдет о командах, которые были созданы специально для файлов. Команды, которые вы можете использовать для работы с файлами:Get-ChildItem Get-Item Copy-Item Move-Item New-Item Remove-Item Rename-Item
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-ChildItem возвращает элементы, обнаруженные в одном или нескольких указанных местах. Местоположение может быть контейнером файловой системы, таким как каталог, или местом, показанным другим провайдером, таким как подраздел реестра или хранилище сертификатов. Вы можете задействовать параметр Recurse данной команды, чтобы добраться до элементов во всех подпапках.
Если использовать эту команду без параметров, она возвращает все дочерние элементы (такие как подпапки и файлы) в текущем местоположении. Например, если текущее местоположение – корневой каталог H, то запуская команду Get-ChildItem, вы получите результаты, похожие на те, что показаны на экране 1.
Экран 1. Результаты работы Get-ChildItem |
Используя параметры, вы можете получить информацию, которая вам нужна. Например, следующая команда возвращает все файлы. log в корневом каталоге C, включая подкаталоги:
Как мы видим, эта команда использует параметры -Include, -Recurse и –Force. Параметр –Include служит для возвращения заданных элементов. Он поддерживает использование групповых символов и является идеальным для указания расширения имени файла. Параметр –Recurse дает PowerShell указание возвращать подпапки наряду с файлами. Параметр –Force добавляет скрытые и системные файлы к выходным данным.
Следующая команда дает те же результаты, что и предыдущая, потому что параметр –Path понимает групповые символы:
Для некоторых параметров команд PowerShell имя параметра вы можете опустить, если знаете, что параметр находится в той позиции, которая нужна PowerShell. Так происходит при использовании параметра –Path команды Get-ChildItem. Таким образом, следующая команда выдаст тот же результат, что и предыдущая команда:
Параметр –Path может принимать множественные аргументы, разделенные запятыми. Например, предположим, что вы хотите возвратить. log-файлы из двух мест: корневого каталога С и корневого каталога Н, последний является текущим (то есть местоположением по умолчанию). Для выполнения этого действия нужно указать значение C:\* для получения всех файлов журналов из корневого каталога С и значение * для получения всех файлов журналов из корневого каталога Н (поскольку корневая папка Н является местоположением по умолчанию, вам не нужно указывать H:\.). Необходимо разделить два аргумента запятой, например так:
В результатах примера на экране 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. Хотя сам параметр и нужен, указывать имя параметра не требуется. Например, вот простая команда, которая использует «точку» для возвращения информации о текущем каталоге (в данном случае корневая папка Н):
Результаты показаны на экране 3. Команда Get-Item позволяет задействовать групповой символ * для возвращения всего содержимого элемента (то есть всех дочерних элементов). Например, следующая команда возвращает весь контент текущего каталога (в данном случае корневого каталога Н). Точка и символ звездочки могут быть использованы как компоненты в пути файла, но вы должны еще указать косую черту как разделитель папок:
Результаты вы можете увидеть на экране 4. Важно понимать, что команды PowerShell, включая Get-Item, возвращают объекты. Команда Get-Item возвращает объекты System.IO.DirectoryInfo, которые содержат несколько методов и свойств, которые вы можете использовать. Чтобы увидеть эти методы и свойства, можно передать результаты команды Get-Item в команду Get-Member. Если вы хотите увидеть эти свойства, можете запустить такую команду:
Как показано на экране 5, свойство LastAccessTime возвращает дату и время, когда к указанному каталогу был в последний раз осуществлен доступ.
Например, если вы хотите выяснить, когда к текущему каталогу был осуществлен доступ в последний раз, вы запускаете команду:
Заметим, что в этой команде вызов Get-Item. заключен в круглые скобки и что между закрывающей круглой скобкой и LastAccessTime стоит точка. Круглые скобки вокруг вызова «Get-Item. » нужны для того, чтобы возвращенные объекты сохранялись в памяти и вы могли бы выполнять с ними дополнительные операции. В этом случае операцией является поиск возвращаемого значения свойства LastAccessTime объекта. В PowerShell вы используете символ точки для получения доступа к ряду свойств объекта и методов. Вот почему следует вставить точку между закрывающейся скобкой и LastAccessTime.
Существует коллекция специальных свойств, которая называется NoteProperty. Вы можете применять ее для того, чтобы сузить выводимые результаты для определенного типа объекта. Вы можете использовать Get-Member с параметром -MemberType NoteProperty, чтобы узнать о специальных свойствах этой коллекции:
Если вы запустите эту команду, то обнаружите, что коллекция возвращает шесть свойств: PSChildName, PSDrive, PSIsContainer, PSParentPath, PSPath и PSProvider. Свойство PSIsContainer коллекции NoteProperty показывает, является ли объект контейнером (папкой). Свойство возвращает True, когда объект является папкой, и False, когда он является файлом. Вы можете использовать это свойство для ограничения вывода Get-Item папками:
Давайте обсудим эту команду подробнее. Ее результаты показаны на экране 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:
Параметр –Path принимает групповые символы, поэтому вы можете копировать несколько файлов сразу. Например, следующая команда копирует все файлы в папке C:\Scripts в папку C:\Backups\Scripts:
Чтобы получить более детальное управление операцией копирования, вы можете задействовать параметры -Recurse, -Filter и –Force. Так, следующая команда копирует все файлы. txt, содержащиеся в C:\Scripts в C:\Temp\Text:
Обратите внимание, что «обратная кавычка» в конце первой строки является символом продолжения строки в PowerShell.
Немного освоившись, вы можете вставить свойство FullName в параметр –Path для копирования тщательно отобранного списка файловых объектов, используя либо Get-Item, либо команду Get-ChildItem:
На самом деле это предложение является комбинацией трех отдельных команд. Первая команда (то есть команда в первой строке) возвращает все файлы. txt в корневом каталоге С. Вторая команда (команда во второй и третьей строках) вычленяет список текстовых файлов таким образом, что содержит только те файловые объекты, чье свойство LastAccessTime больше, чем месяц назад. Третья команда (команда в последней строке) вставляет каждое файловое имя в свойство –Path, располагающееся в Copy-Item, используя команду ForEach-Object. Слишком сложно для вас? Тогда можете принять входные данные по конвейеру. Только убедитесь, что вы указали имя параметра –Destination так, чтобы Copy-Item знала, что делать с этими входными данными, так как данный параметр находится не в ожидаемой позиции:
Хотя в наших примерах это и не показано, вы можете обратиться к Copy-Item через дополнительные имена. Существует три псевдонима: copy, cp, cpi.
Использование Move-Item
Move-Item очень похожа на Copy-Item. Фактически, если вы заменяете Copy-Item на Move-Item в любой из команд, представленных в предыдущем разделе, команды будут вести себя во многом так же, за исключением того, что исходные файлы будут удалены в исходную папку.
Однако есть одно важное различие. Если вы запустите одну и ту же команду Copy-Item дважды, то обнаружите, что PowerShell переписывает существующий файл в папку назначения без какого-либо предупреждения.
Move-Item более осторожна в этом смысле и вместо удаления выдает ошибку. Например, если вы запускаете команду
то получите ошибку Cannot create a file («нельзя создать файл»), так как файл уже существует. Использование параметра –Force приводит к тому, что Move-Item переписывает существующий файл.
Помимо параметра –Force, вы можете задействовать параметры Recurse и –Filter в команде Move-Item, чтобы настраивать ее. Например, следующая команда перемещает текстовые файлы в папке C:\Scripts и ее подпапках в папку C:\Temp\Text. В данном случае вам нужно указать имя параметра –Destination, поскольку вы не используете этот параметр в той позиции, где его ожидает PowerShell:
Как и Copy-Item, Move-Item имеет три псевдонима: move, mv и mi.
Использование New-Item
New-Item играет двойную роль — создателя каталога и файла (кроме того, она может создавать разделы и параметры реестра). Когда вы хотите создать файл, вам нужно указать параметры –Path и –ItemType. Как было показано выше, параметр –Path является позиционным, таким образом, не требуется имя параметра –Path, когда вы задаете путь и имя (то есть путь к файлу) сразу же после имени команды. Также следует указать параметр –ItemType при помощи флажка»file«. Вот пример:
Параметр –Path может принимать массив строк так, что вы можете создавать несколько файлов за раз. Вам просто нужно разделить пути при помощи запятых. Вдобавок, необходимо вставить сначала параметр -ItemType»file«, который означает, что вам нужно указать имя параметра –Path, поскольку он теперь не первый параметр после имени команды:
Если файл с точно таким же именем пути файла уже существует, вы получите ошибку. Однако вы можете указать параметр –Force так, что New-Item перепишет существующий файл.
Что на самом деле примечательно, так это то, что New-Item позволяет вставлять текст в файл посредством параметра –Value:
Не забудьте указать параметр –Force, если файл уже существует. Иначе система выдаст ошибку.
Параметр –Value может принимать ввод данных по конвейеру, что является отличным способом перенаправлять вывод данных других команд в файл. Вам нужно просто конвертировать выходные объекты в строку, используя Out-String (если вы этого не сделаете, New-Item создаст новый файл для каждого объекта). Например, следующая команда возвращает информацию обо всех файлах из корневого каталога С, конвертирует информацию о файлах в строку, а затем пишет эту информацию в файл H:\C Listing.txt:
New-Item имеет только одно встроенное дополнительное имя: ni.
Использование Remove-Item
Remove-Item навсегда удаляет ресурс с указанного диска, то есть она не перемещает его в корзину. Таким образом, если вы используете Remove-Item для удаления файла, то нет иного способа вернуть его, кроме как через программу восстановления файлов.
Вы указываете, какой файл должна удалять Remove-Item при помощи параметра –Path. Он позиционный, поэтому вам не нужно указывать имя параметра –Path, если оно идет сразу же за именем команды. Например, вот команда для удаления файла test.txt, который был ранее скопирован в папку C:\Backups\Scripts:
Давайте рассмотрим другой пример. Следующая команда удаляет все файлы. txt (что указано в параметре –Include) в папке C:\Scripts, кроме тех файлов, которые имеют слово test где-либо в файловом имени (что указано в параметре –Exclude):
Будучи, по сути, опасным инструментом, Remove-Item предоставляется с парой элементов защиты. Прежде всего, если вы пытаетесь удалить все из папки, которая содержит непустые подпапки, вы получите запрос на подтверждение Confirm. Например, предположим, что C:\Scripts содержит непустые подпапки и вы запускаете такую команду:
Нужно подтвердить, что вы хотите удалить непустые подпапки, как показано на экране 7.
Экран 7. Запрос на подтверждение удаления при использовании Remove-Item |
Если вы хотите запустить сценарий, который использует Remove-Itemм для удаления всего содержимого папок, включая содержимое подпапок, вам нужен способ запускать Remove-Item без участия пользователя. Этот способ – включение флажка –Recurse.
Второй элемент защиты – это параметр –WhatIf. Если вы включаете его в команду Remove-Item, то PowerShell покажет, какие элементы будут удалены, вместо того, чтобы просто удалить их. В силу деструктивной природы операций удаления, имеет смысл выполнять пробное применение команды Remove-Item с параметром –WhatIf, как здесь:
Экран 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, вам потребуется запустить такую команду:
Поскольку -Path и -NewName являются позиционными параметрами, вы можете пропускать имена параметров до тех пор, пока они находятся в ожидаемых позициях:
Например, следующая команда перечисляет все файлы в текущем каталоге и переименовывает каждый файл, заменяя все пробелы в файловых именах на подчеркивания:
Rename-Item имеет два псевдонима: ren и rni.
Великолепная семерка
В данном руководстве я познакомил вас со способами взаимодействия PowerShell с файлами. В частности, мы изучили встроенные команды PowerShell, предназначенные для работы с файлами. Это Get-ChildItem, Get-Item, Copy-Item, Move-Item, New-Item, Remove-Item и Rename-Item.
Я пытаюсь просто удалить первую строку около 5000 текстовых файлов перед их импортом.
Я все еще очень новичок в PowerShell, поэтому не уверен, что искать или как подойти к этому. Моя текущая концепция с использованием псевдо-кода:
однако я не могу понять, как сделать что-то вроде contains.
Это не самый эффективный в мире, но это должно работать:
в то время как я действительно восхищаюсь ответом от @hoge как для очень краткой техники, так и для функции обертки, чтобы обобщить ее, и я поощряю upvotes для нее, я вынужден комментировать два других ответа, которые используют временные файлы (он грызет меня, как ногти на доске!).
предполагая, что файл не огромен, вы можете заставить конвейер работать в дискретных секциях-тем самым устраняя необходимость в временном файле-с разумным использованием скобки:
. или в краткой форме:
используя переменную нотацию, вы можете сделать это без временного файла:
мне просто нужно было выполнить ту же задачу, и gc | select . | sc взял на себя 4 ГБ ОЗУ на моей машине при чтении файла 1.6 GB. Он не заканчивался по крайней мере в течение 20 минут после чтения всего файла (как сообщает Read Bytes in Процесс Explorer), и в этот момент мне пришлось убить его.
ниже мое решение. Да, он использует временный файл, но в моем случае это не имело значения (это было чертовски огромное создание таблицы SQL и файл инструкций insert):
вдохновленный ответ AASoft, Я вышел, чтобы улучшить его немного подробнее:
- избежать переменная цикла $i и сравнение С 0 в каждом цикле
- оберните исполнение в try..finally блок, чтобы всегда закрывать файлы в использовании
- сделать решение работать для произвольное количество строк удалить С начала файла
- использовать переменную $p для ссылки на текущий каталог
эти изменения приводят к следующим кодом:
первое изменение принесло время обработки для моего файла 60 MB вниз от 5.3s to 4s . Остальные изменения носят более косметический характер.
Я только что узнал из сайта:
или вы можете использовать псевдонимы, чтобы сделать это коротко, как:
skip` не работает, поэтому мой обходной путь
именно столько. Далее следует длинное скучное объяснение. Get-content возвращает массив. Мы можем "индексировать" переменные массива, как показано в этой и другое сценаристы посты.
например, если мы определяем переменную массива, как это,
Итак, $ array возвращает
тогда мы можем "индексировать" этот массив, чтобы получить только его 1-й элемент
Я пытаюсь просто удалить первую строку из примерно 5000 текстовых файлов, прежде чем импортировать их.
Я все еще очень новичок в PowerShell, поэтому не уверен, что искать и как подойти к этому. Моя текущая концепция с использованием псевдокода:
Однако я не могу понять, как сделать что-то вроде содержащего.
Это не самый эффективный в мире, но это должно работать:
В то время как я действительно восхищаюсь ответом от @hoge как для очень краткой техники, так и для функции обертки, чтобы обобщить ее, и я поощряю ее, я вынужден прокомментировать два других ответа, которые используют временные файлы (он грызет мне, как ногти на доске!).
Предполагая, что файл не огромен, вы можете заставить конвейер работать в дискретных разделах - тем самым устраняя необходимость в временном файле - с разумным использованием круглых скобок:
. или в краткой форме:
Используя нотацию переменных, вы можете сделать это без временного файла:
Мне просто нужно было выполнить одну и ту же задачу, а gc | select . | sc заняла 4-х гигабайт ОЗУ на моей машине, читая файл размером 1,6 фунта. Он не завершился в течение как минимум 20 минут после прочтения всего файла (как сообщается Read Bytes в Process Explorer), при котором Я должен был убить его.
Ниже мое решение. Да, он использует временный файл, но в моем случае это не имело значения (это было огромное создание таблицы SQL и вставка файла инструкций):
Вдохновленный ответом AASoft, я вышел, чтобы улучшить его немного больше:
- Избегайте переменной цикла $i и сравнения с 0 в каждом цикле
- Оберните выполнение в блок try..finally , чтобы всегда закрывать используемые файлы
- Сделайте решение для произвольного количества строк для удаления с начала файла
- Используйте переменную $p для ссылки на текущий каталог
Эти изменения приводят к следующему коду:
Первое изменение привело к тому, что время обработки моего 60-мегабайтного файла сократилось с 5.3s до 4s . Остальные изменения более косметичны.
Для открытия файлов и чтения его содержимого используется команда Powershell Get-Content. В этой статье рассмотрим работу команды с открытием файла, построчным чтением, поиском по содержимому строки на примерах.
Навигация по посту
Получение данных
Если у вас множество файлов или вы не уверены в назывании, то вы можете использовать подстановку. Символы подстановок бывают следующих типов:
Каждый из символов выше можно применять вместе и неограниченное число раз, в любой части пути и имени.
В этом примере я открою сразу два файла: lmhosts и hosts:
Следующие примеры вернут аналогичный результат:
Для похожей фильтрации есть следующие параметры, которые так же позволяют использовать символы подстановок:
- Include - в этом параметре мы добавляем шаблон, по которому будем включать файл;
- Exclude - с помощью этого параметра исключает файлы;
- Filter - исключает результаты.
Полное и построчное чтение с поиском
По умолчанию, если мы будем передавать результат команды через конвейер Powershell вывод будет построчный. Это может составить проблему, так как при дополнительных условиях у нас будет возвращаться одна строка, а не весь текст:
Что бы текст передавался полностью, а не построчно - используйте параметр Raw:
Если вам вдруг понадобится выводить по 2 или более строк за раз, можно указать их количество через ReadCount:
Разделение файла
То есть результат выше - это массив. В массивах Powershell мы можем получать содержимое по индексам. В следующем примере я просто уберу точку с запятой:
Подсчет количества строк
Построчный вывод с командой Powershell позволяет посчитать количество строк во всем файле. Для подсчета используется команда Measure-Object:
Если нужна только цифра, а не объект, можно сделать так:
Кодировки
В параметре -Encoding можно указать следующие кодировки:
- ASCII
- BigEndianUnicode
- BigEndianUTF32
- Byte
- Default
- OEM
- Unicode
- UTF7
- UTF8
- UTF32
Как искать файлы используя Powershell Get-ChildItem
Чтения файла под другим пользователем
В этом командлете не предусмотрена возможность открытия файла под другим пользователем. При любых попытках вы будете получать ошибки:
- Access to the path is denied
- The FileSystem provider supports credentials only on the New-PSDrive cmdlet. Perform the operation again without specifying credentials.
Для обхода этих ошибок, если у вас нет другого выхода, нужно использовать Invoke-Command (команда удаленного подключения). Для ее настройки могут потребоваться дополнительные настройки описанные в другой статье.
Сам процесс открытия файла под другим пользователем будет выглядеть так:
Непрерывное чтение
С помощью параметра Wait вы можете читать файл, который в этот момент обновляется системой или другим пользователем:
Ограничение вывода строк
Можно ограничить вывод содержимого файла указав количество нужных строк в начале или конце:
- Head - выведет указанное количество строк с начала;
- Tail - выведет указанное количество строк с конца.
Так будут выведены только первые 5 строк:
Создание и изменение в Powershell NTFS разрешений ACL
Поиск файлов по содержимому
Get-Content не позволяет искать и открывать фалы находящиеся внутри других каталогов. Такой поиск называется рекурсивным и он доступен в Get-ChildItem.
В следующем примере мы вернем файлы из всех каталогов и подкаталогов:
File - возвращает только файлы. Каталоги нам не нужны.
С Get-ChildItem вы так же можете использовать Include,Exclude и Filter, которые были рассмотрены раннее. Использовать эти ключи лучше всего в первой команде т.к. это будет работать быстрее.
Если убрать параметр Raw, то у нас выведется только та строка, которую мы искали:
Изменение файла с последующей записью
Или с помощью регулярного выражения (не точный шаблон):
Второй вариант - использовать команду Set-Content:
Функции по работе со строками в Powershell
Подсчет четных чисел в файле
Для выделения таких чисел из строк нужно использовать Select-String:
Нам нужно отформатировать вывод убрав пустые строки и получить значения свойства Value:
Мы можем вернуть остаток от деления использовав %. Если число делится на 2 с остатком 0, то оно будет четным:
Читайте также: