Используя PowerShell, я хочу заменить все точные вхождения [MYID]
в данном файле MyValue
. Какой самый простой способ сделать это?
powershell
любитель
источник
источник
Ответы:
Используйте (версия V3):
Или для V2:
источник
Обратите внимание, круглые скобки
(Get-Content file.txt)
обязательны для заполнения:источник
Set-Content
вместоOut-File
вас, вы получите предупреждение типа «Процесс не может получить доступ к файлу« 123.csv », потому что он используется другим процессом». ,Get-Content
в скобках это работает. Можете ли вы объяснить в своем ответе, почему скобки необходимы? Я бы еще заменитьOut-File
с ,Set-Content
потому что это безопаснее; он защищает вас от удаления целевого файла, если вы забудете скобки.Set-Content
вместоOut-File
гораздо лучшего и более безопасного решения. Извините, надо понизить.Я предпочитаю использовать File-класс .NET и его статические методы, как показано в следующем примере.
Это имеет преимущество работы с одной строкой вместо массива строк, как с Get-Content . Методы также заботятся о кодировке файла (UTF-8 BOM и т. Д.), При этом вам не нужно заботиться большую часть времени.
Кроме того, методы не портят окончания строк (которые могут использоваться в конце строк Unix), в отличие от алгоритма, использующего Get-Content и передающего по конвейеру Set-Content. .
Так что для меня: меньше вещей, которые могут сломаться за эти годы.
Малоизвестная вещь при использовании классов .NET заключается в том, что, когда вы ввели «[System.IO.File] ::» в окне PowerShell, вы можете нажать Tabклавишу, чтобы пройти через все эти методы.
источник
[System.IO.File] | gm
C:\Windows\System32\WindowsPowerShell\v1.0
?Вышеприведенный пример работает только для «одного файла», но вы также можете запустить его для нескольких файлов в вашей папке:
источник
foreach
вы можете сделать этоGet-ChildItem 'C:\folder\file*.xml' -Recurse | ForEach { (Get-Content $_).Replace('[MYID]', 'MyValue') | Set-Content $_ }
foreach
, потому что Get-Content делает то, чего вы не ожидаете ... Он возвращает массив строк, где каждая строка является строкой в файле. Если вы просматриваете каталог (и подкаталоги), который находится в другом месте, чем ваш выполняемый скрипт, вам понадобится что-то вроде этого:Get-ChildItem $Directory -File -Recurse | ForEach { (Get-Content $_.FullName) | ForEach { $_ -replace '[MYID]', 'MyValue' } | Set-Content $_.FullName }
где$Directory
находится каталог, содержащий файлы, которые вы хотите изменить.Вы можете попробовать что-то вроде этого:
источник
Это то, что я использую, но это медленно на больших текстовых файлах.
Если вы собираетесь заменять строки в больших текстовых файлах, а скорость - проблема, посмотрите на использование System.IO.StreamReader и System.IO.StreamWriter .
(Код выше не был проверен.)
Вероятно, есть более элегантный способ использовать StreamReader и StreamWriter для замены текста в документе, но это должно дать вам хорошую отправную точку.
источник
Я нашел малоизвестный, но удивительно крутой способ сделать это из Windows PowerShell от Payette в действии . Вы можете ссылаться на файлы, такие как переменные, похожие на $ env: path, но вам нужно добавить фигурные скобки.
источник
$myFile
?$a = 'file.txt'; invoke-expression "`${c:$a} = `${c:$a} -replace 'oldvalue','newvalue'"
Если вам нужно заменить строки в нескольких файлах:
Следует отметить, что различные методы, размещенные здесь, могут сильно отличаться в зависимости от времени, которое требуется для завершения. Для меня у меня регулярно есть большое количество маленьких файлов. Чтобы проверить, что является наиболее производительным, я извлек 5,52 ГБ (5 933 604 999 байт) XML в 40 693 отдельных файлах и пробежал три ответа, которые я нашел здесь:
источник
Кредит @ rominator007
Я обернул его в функцию (потому что вы можете использовать его снова)
ПРИМЕЧАНИЕ: это НЕ чувствительно к регистру !!!!!
Смотрите этот пост: String.Заменить игнорируя регистр
источник
Это работало для меня, используя текущий рабочий каталог в PowerShell. Вам нужно использовать это
FullName
свойство, иначе оно не будет работать в PowerShell версии 5. Мне нужно было изменить целевую версию платформы .NET во ВСЕХ моихCSPROJ
файлах.источник
Немного старый и другой, так как мне нужно было изменить определенную строку во всех экземплярах определенного имени файла.
Кроме того,
Set-Content
не возвращал последовательных результатов, поэтому мне пришлось прибегнуть кOut-File
.Код ниже:
Вот что лучше всего сработало для меня в этой версии PowerShell:
источник
Небольшое исправление для команды Set-Content. Если искомая строка не найдена,
Set-Content
команда очистит (очистит) целевой файл.Вы можете сначала проверить, существует ли искомая строка или нет. Если нет, то это ничего не заменит.
источник
set-content test.txt "hello hello world hello world hello"
и тогда(get-content .\test.txt).Replace("something", "awesome") | set-content .\test.txt
не будет очищать файл, как предложено в этом.