Mon fichier de configuration d'origine (web1.config) n'a pas de ligne supplémentaire et lorsqu'il est affiché dans le bloc-notes (affichant tous les caractères), il ressemble à:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.6" />
<httpRuntime targetFramework="4.6" />
</system.web>
<appSettings>
<add key="myConnectionString" value="server=localhost;database=myDb;uid=myUser;password=myPass;" />
</appSettings>
</configuration>
Maintenant, je dois appliquer le script pour changer le nom de ma base de données en quelque chose d'autre qui ressemble à:
Move-Item "web1.config" "webtemp.config"
Get-Content "webtemp.config" | ForEach-Object {$_ -replace "database=myDb;", "database=newDb;"} |Set-Content "web1.config" -Force
Remove-Item "webtemp.config"
Write-Output('Settings Changed')
Ainsi, le nouveau fichier (web1.config) généré ressemble à:
Remarquez la ligne supplémentaire ajoutée à la fin du fichier (ce qui n'est absolument pas nécessaire). J'ai essayé toutes les autres options telles que: - en utilisant l'api hors fichier - en utilisant .net IO méthode System.IO .StreamWriter - en utilisant l'indicateur -nonewline (il convertit les 10 lignes en une seule ligne) - en utilisant différentes options de codage - a essayé de remplacer\r\n en\r (ne fonctionne pas car set-content génère toujours le crlf)
J'utilise PowerShell v5.1.
tl; dr ( PSv5 +; voir en bas pour les anciennes versions):
(Get-Content webtemp.config) -replace "database=myDb;","database=newDb;" -join "`n" |
Set-Content -NoNewline -Force web1.config
Remarque: Remplacez "`n"
Par "`r`n"
Si vous voulez des fins de ligne CRLF de style Windows plutôt que des fins de ligne LF uniquement Unix (PowerShell et de nombreux utilitaires peuvent gérer les deux).
Dans PSv5 + , Set-Content
Prend en charge le commutateur -NoNewline
, qui demande à Set-Content
de ne pas ajouter de nouvelle ligne (saut de ligne) après chaque objet d'entrée . Il en va de même pour les applets de commande Add-Content
Et Out-File
.
En d'autres termes: Set-Content -NoNewline
concatène directement les représentations de chaîne de tous ses objets d'entrée :
> 'one', 'two' | Set-Content -NoNewline tmp.txt; Get-Content tmp.txt
onetwo
Si ce que vous passez à Set-Content -NoNewline
Est un chaîne unique qui a déjà des nouvelles lignes intégrées, vous pouvez l'utiliser tel quel et obtenir le résultat souhaité:
> "one`ntwo" | Set-Content -NoNewline tmp.txt; "$(Get-Content -Raw tmp.txt)?"
one
two?
Notez que Get-Content -Raw
Lit le fichier dans son ensemble, tel quel (à part le décodage des caractères) et le fait que ?
Apparaît directement après two
implique que le fichier n'a pas de nouvelle ligne de fin.
Dans votre cas, puisque vous traitez les lignes d'entrée un par un (via Get-Content
sans-Raw
) Et donc sortir un tableau de lignes (chaînes), vous devez d'abord les joindre avec une nouvelle ligne comme séparateur - entre lignes uniquement - et passez le résultat à Set-Content -NoNewline
, comme indiqué en haut; voici un exemple simplifié:
> ('one', 'two') -join "`n" | Set-Content -NoNewline tmp.txt; "$(Get-Content -Raw tmp.txt)?"
one
two?
'one', 'two'
Est un tableau de chaînes à deux éléments qui remplace votre commande de traitement ligne par ligne.
Note d'encodage:
Dans Windows PowerShell, Set-Content
Produit par défaut des fichiers codés "ANSI", basés sur la page de code à un octet héritée de votre système.
Pour contrôler explicitement l'encodage, utilisez le paramètre -Encoding
.
Dans PSv4 - , une solution qui utilise le .NET Framework est nécessaire:
> [System.IO.File]::WriteAllText('tmp.txt', ('one', 'two') -join "`n"); "$(Get-Content -Raw tmp.txt)?"
one
two?
Notez que [System.IO.File]::WriteAllText()
, en l'absence d'argument de codage, par défaut est UTF-8 sans nomenclature.
Passez l'instance d'encodage [System.Text.Encoding]
Souhaitée en tant que 3e argument selon les besoins.
Je n'ai jamais remarqué cela, alors j'ai fait une recherche rapide et j'ai trouvé:
set-content ajoute des sauts de ligne par défaut
La solution suggérée consiste à coder votre contenu en octets, puis à utiliser Set-Content avec le paramètre -Encoding.
Set-Content test.txt ([byte[]][char[]] "test") -Encoding Byte
Je l'ai testé moi-même afin que je puisse confirmer que cela fonctionne.