Comment concaténer deux fichiers texte dans PowerShell?

108

J'essaye de reproduire la fonctionnalité de la catcommande sous Unix.

Je voudrais éviter les solutions où je lis explicitement les deux fichiers dans des variables, concatène les variables ensemble, puis écris la variable concaténée.

merlin2011
la source

Réponses:

170

Vous pouvez simplement utiliser cat example1.txt, example2.txt | sc examples.txt. Vous pouvez également concaténer plus de deux fichiers avec ce style. De plus, si les fichiers sont nommés de la même manière, vous pouvez utiliser:

cat example*.txt | sc allexamples.txt

Le catest un alias pour Get-Contentet scest un alias pour Set-Content.

Remarque 1 : soyez prudent avec cette dernière méthode - si vous essayez de générer une sortie vers examples.txt(ou similaire qui correspond au modèle), PowerShell entrera dans une boucle infinie! (Je viens de tester ça).

Remarque 2 : La sortie dans un fichier avec >ne préserve pas le codage des caractères! C'est pourquoi il est recommandé d' utiliser Set-Content( sc).

Smi
la source
5
Juste au cas où quelqu'un voudrait parcourir des fichiers avec Get-ChildItems | Pour chaque construction d' objet, vous souhaiterez peut-être utiliser Add-Content au lieu de Set-Content. Sinon, le fichier cible est écrasé à chaque itération.
Jonas
1
Notez que par défaut Set-Contentutilise la page de codes nationale (par exemple Windows-1252 pour l'anglais). Si les fichiers source contiennent un autre codage (par exemple, Windows-1251 ou UTF8), vous devez définir un codage correct sc file.txt -Encoding UTF8(des nombres tels que 1251 pour le russe sont pris en charge depuis la v6.2)
Radek Pech
@Jonas Le problème avec Add-Contentest que si vous exécutez la commande deux fois, le fichier agrégé est deux fois plus long. Un bon remplacement est Out-File. Exemple ici
Dan Friedman
1
Cela ne semble pas fonctionner si les fichiers sont binaires (par exemple, des parties d'un fichier zip dans mon cas).
Daniel Lidström
1
@ DanielLidström Cela fonctionne également pour les binaires avec les paramètres corrects: Get-Content my.bin -Raw | Set-Content my.bin -NoNewlinene changera pas my.binsauf les horodatages. -Rawpréserve tous les octets CR / LF, tout en -NoNewlineempêchant PowerShell d'ajouter ses propres octets CR / LF.
Thomas le
62

Ne pas utiliser >; cela perturbe l'encodage des caractères. Utilisation:

Get-Content files.* | Set-Content newfile.file
user2074686
la source
catest un alias pour Get-Content.
n0rd
5
@ n0rd Je pense que c'était plus une chose "utiliser le pipeline à la place".
ksoo
Peut confirmer. Obtient ce ÿþqui est FF FEau début de mon fichier concaténé lors de l'utilisation >.
gpresland
16

Dans cmd, vous pouvez faire ceci:

copy one.txt+two.txt+three.txt four.txt

Dans PowerShell, ce serait:

cmd /c copy one.txt+two.txt+three.txt four.txt

Alors que la manière PowerShell serait d'utiliser gc , ce qui précède sera assez rapide, en particulier pour les fichiers volumineux. Et il peut également être utilisé sur des fichiers non ASCII en utilisant le /Bcommutateur.

manojlds
la source
3
Pour moi, la commande cat exécute plusieurs ordres de grandeur plus longtemps que la commande cmd / c (qui s'exécute très rapidement); merci d'avoir signalé l'option!
Rob
C'est la meilleure réponse.
Nicholas DiPiazza
12

Vous pouvez utiliser l' applet de commande Add-Content . C'est peut-être un peu plus rapide que les autres solutions, car je ne récupère pas le contenu du premier fichier.

gc .\file2.txt| Add-Content -Path .\file1.txt
mjsr
la source
À quoi fait gcréférence?
octopusgrabbus
gcest un alias pour Get-Content
MM.
8

Pour concater des fichiers dans l'invite de commande, ce serait

type file1.txt file2.txt file3.txt > files.txt

PowerShell convertit la typecommande en Get-Content, ce qui signifie que vous obtiendrez une erreur lors de l'utilisation de la typecommande dans PowerShell, car la Get-Contentcommande nécessite une virgule séparant les fichiers. La même commande dans PowerShell serait

Get-Content file1.txt,file2.txt,file3.txt | Set-Content files.txt
Brian Kimball
la source
5

Si vous avez besoin de classer les fichiers par paramètre spécifique (par exemple, date et heure):

gci *.log | sort LastWriteTime | % {$(Get-Content $_)} | Set-Content result.log
O romain
la source
3

J'ai utilisé:

Get-Content c:\FileToAppend_*.log | Out-File -FilePath C:\DestinationFile.log 
-Encoding ASCII -Append

Cette amende ajoutée. J'ai ajouté le codage ASCII pour supprimer les caractères nuls que Notepad ++ montrait sans le codage explicite.

Phoenix14830
la source
2

Vous pouvez faire quelque chose comme:

get-content input_file1 > output_file
get-content input_file2 >> output_file

>est un alias pour "out-file", et >> est un alias pour "out-file -append".

vlad-ardelean
la source
2

Étant donné que la plupart des autres réponses ont souvent une mauvaise mise en forme (en raison de la tuyauterie), la chose la plus sûre à faire est la suivante:

add-content $YourMasterFile -value (get-content $SomeAdditionalFile)

Je sais que vous vouliez éviter de lire le contenu de $ SomeAdditionalFile dans une variable, mais pour enregistrer par exemple votre mise en forme de nouvelle ligne, je ne pense pas qu'il y ait un moyen approprié de le faire sans.

Une solution de contournement serait de parcourir votre $ SomeAdditionalFile ligne par ligne et de le rediriger vers votre $ YourMasterFile. Cependant, cela demande trop de ressources.

Kamaradski
la source
1

Pour conserver l'encodage et les fins de ligne:

Get-Content files.* -Raw | Set-Content newfile.file -NoNewline

Remarque: AFAIR, dont les paramètres ne sont pas pris en charge par les anciens Powershells (<3? <4?)

Ilyan
la source
0

Je pense que la "façon PowerShell" pourrait être:

set-content destination.log -value (get-content c:\FileToAppend_*.log )
dvjz
la source