Скорее всего, вы стали жертвой непоследовательной строки Windows PowerShell для System.IO.FileInfo
экземпляров, выводимых Get-ChildItem
- см. этот ответ .
Обходной путь - использовать явную строкучерез свойство .FullName
, которое явно возвращает полный путь к элементу.
Применяется к вашей команде наряду с некоторыми оптимизациями:
Get-ChildItem -File -Recurse src | ForEach-Object {
$f = $_.FullName # !! Explicitly retrieve the full path
(Get-Content $f -Raw) -creplace 'Find', 'Replace' |
Set-Content -NoNewline "$f.tmp"
Move-Item "$f.tmp" $f -Force
}
Get-Content -Raw
читаетвесь файл в памяти в виде одной строки, что более эффективно.
-creplace
(который выполняет замену с учетом регистра , как sed
по умолчанию) непосредственно применяется к результирующей многострочной строке и заменяет все вхождения.
-NoNewline
(PSv5 +) гарантирует, что Set-Content
не добавит дополнительный трейлингперевод строки в сохраняемую многострочную строку (то же самое относится к Out-File
/ >
).
Примечание. Учитывая, что Get-Content -Raw
читает весь файл заранее, вы даже можете записать измененное содержимое обратно в тот же файл, не требуя промежуточного временного файла и последующего Move-Item
звонок;Тем не менее, выполнение этого несет небольшой риск потери данных, если процесс обратной записи в тот же файл прерывается.
- Кроме того, в то время как ваш вызов
sed
сохраняет исходный файл с расширением .bak
, ваша команда PowerShell не выполняет.