Con PowerShell, quiero reemplazar todas las ocurrencias exactas de [MYID]
un archivo determinado con MyValue
. ¿Cuál es la forma más fácil de hacerlo?
powershell
aficionado
fuente
fuente
Respuestas:
Uso (versión V3):
O para V2:
fuente
Tenga en cuenta que los paréntesis
(Get-Content file.txt)
son obligatorios:fuente
Set-Content
lugar de aOut-File
usted, aparece una advertencia como "El proceso no puede acceder al archivo '123.csv' porque está siendo utilizado por otro proceso". .Get-Content
paréntesis funciona. ¿Puedes explicar en tu respuesta por qué es necesario el paréntesis? Me gustaría volver a reemplazarOut-File
conSet-Content
porque es más seguro; te protege de borrar el archivo de destino si olvidas el paréntesis.Set-Content
lugar deOut-File
es una solución mucho mejor y más segura. Lo siento, tengo que votar a favor.Prefiero usar la clase de archivo de .NET y sus métodos estáticos como se ve en el siguiente ejemplo.
Esto tiene la ventaja de trabajar con una sola cadena en lugar de una serie de cadenas como con Get-Content . Los métodos también se encargan de la codificación del archivo (UTF-8 BOM , etc.) sin que tenga que preocuparse la mayor parte del tiempo.
Además, los métodos no estropean las terminaciones de línea (terminaciones de línea Unix que podrían usarse) en contraste con un algoritmo que usa Get-Content y pasa a Set-Content .
Entonces para mí: Menos cosas que podrían romperse con los años.
Algo poco conocido al usar clases .NET es que cuando ha escrito "[System.IO.File] ::" en la ventana de PowerShell, puede presionar la Tabtecla para recorrer los métodos allí.
fuente
[System.IO.File] | gm
C:\Windows\System32\WindowsPowerShell\v1.0
?El anterior solo se ejecuta para "Un archivo", pero también puede ejecutarlo para varios archivos dentro de su carpeta:
fuente
foreach
, puede hacerloGet-ChildItem 'C:\folder\file*.xml' -Recurse | ForEach { (Get-Content $_).Replace('[MYID]', 'MyValue') | Set-Content $_ }
foreach
, porque Get-Content hace algo que no podrías esperar ... Devuelve una matriz de cadenas, donde cada cadena es una línea en el archivo. Si está recorriendo un directorio (y subdirectorios) que se encuentran en una ubicación diferente a su script en ejecución, querrá algo como esto:Get-ChildItem $Directory -File -Recurse | ForEach { (Get-Content $_.FullName) | ForEach { $_ -replace '[MYID]', 'MyValue' } | Set-Content $_.FullName }
dónde$Directory
está el directorio que contiene los archivos que desea modificar.Podrías probar algo como esto:
fuente
Esto es lo que uso, pero es lento en archivos de texto grandes.
Si va a reemplazar cadenas en archivos de texto grandes y la velocidad es una preocupación, considere usar System.IO.StreamReader y System.IO.StreamWriter .
(El código anterior no ha sido probado).
Probablemente haya una forma más elegante de usar StreamReader y StreamWriter para reemplazar texto en un documento, pero eso debería proporcionarle un buen punto de partida.
fuente
Encontré una forma poco conocida pero asombrosa de hacerlo desde Windows Powershell en acción de Payette . Puede hacer referencia a archivos como variables, similares a $ env: path, pero debe agregar las llaves.
fuente
$myFile
?$a = 'file.txt'; invoke-expression "`${c:$a} = `${c:$a} -replace 'oldvalue','newvalue'"
Si necesita reemplazar cadenas en varios archivos:
Cabe señalar que los diferentes métodos publicados aquí pueden ser muy diferentes con respecto al tiempo que lleva completar. Para mí, regularmente tengo grandes cantidades de archivos pequeños. Para probar cuál es el más eficiente, extraje 5.52 GB (5,933,604,999 bytes) de XML en 40,693 archivos separados y analicé tres de las respuestas que encontré aquí:
fuente
Crédito a @ rominator007
Lo envolví en una función (porque es posible que desee usarlo nuevamente)
NOTA: ¡Esto NO distingue entre mayúsculas y minúsculas!
Ver esta publicación: String . Reemplazar ignorando mayúsculas y minúsculas
fuente
Esto funcionó para mí usando el directorio de trabajo actual en PowerShell. Necesita usar la
FullName
propiedad, o no funcionará en PowerShell versión 5. Necesitaba cambiar la versión de destino de .NET framework en TODOS misCSPROJ
archivos.fuente
Un poco viejo y diferente, ya que necesitaba cambiar una línea determinada en todas las instancias de un nombre de archivo en particular.
Además,
Set-Content
no estaba devolviendo resultados consistentes, así que tuve que recurrir aOut-File
.Código a continuación:
Esto es lo que funcionó mejor para mí en esta versión de PowerShell:
fuente
Pequeña corrección para el comando Establecer contenido. Si no se encuentra la cadena buscada, la
Set-Content
comando dejará en blanco (vacío) el archivo de destino.Primero puede verificar si la cadena que está buscando existe o no. Si no, no reemplazará nada.
fuente
set-content test.txt "hello hello world hello world hello"
y luego(get-content .\test.txt).Replace("something", "awesome") | set-content .\test.txt
no vaciará el archivo como se sugiere en esto.