Wie verkette ich zwei Textdateien in PowerShell?

108

Ich versuche, die Funktionalität des catBefehls unter Unix zu replizieren .

Ich möchte Lösungen vermeiden, bei denen ich beide Dateien explizit in Variablen einlese, die Variablen miteinander verkette und dann die verkettete Variable ausschreibe.

merlin2011
quelle

Antworten:

170

Sie können einfach verwenden cat example1.txt, example2.txt | sc examples.txt. Mit diesem Stil können Sie sicherlich auch mehr als zwei Dateien verketten. Wenn die Dateien ähnlich benannt sind, können Sie außerdem Folgendes verwenden:

cat example*.txt | sc allexamples.txt

Das catist ein Alias ​​für Get-Contentund scist ein Alias ​​für Set-Content.

Hinweis 1 : Seien Sie vorsichtig mit der letzteren Methode. Wenn Sie versuchen, eine Ausgabe zu erstellen examples.txt(oder eine ähnliche Methode , die dem Muster entspricht), gerät PowerShell in eine Endlosschleife! (Ich habe das gerade getestet).

Hinweis 2 : Bei der Ausgabe in eine Datei mit >bleibt die Zeichencodierung nicht erhalten! Aus diesem Grund wird die Verwendung von Set-Content( sc) empfohlen.

Smi
quelle
5
Nur für den Fall, dass jemand Dateien mit Get-ChildItems | durchlaufen möchte Für jedes Objektkonstrukt möchten Sie möglicherweise Add-Content anstelle von Set-Content verwenden. Andernfalls wird die Zieldatei bei jeder Iteration überschrieben.
Jonas
1
Beachten Sie, dass standardmäßig Set-Contenteine nationale Codepage verwendet wird (z. B. Windows-1252 für Englisch). Wenn die Quelldateien eine andere Codierung enthalten (z. B. Windows-1251 oder UTF8), müssen Sie die richtige Codierung festlegen sc file.txt -Encoding UTF8(Zahlen wie 1251 für Russisch werden seit Version 6.2 unterstützt)
Radek Pech
@ Jonas Das Problem dabei Add-Contentist, dass die aggregierte Datei doppelt so lang ist, wenn Sie den Befehl zweimal ausführen. Ein guter Ersatz ist Out-File. Beispiel hier
Dan Friedman
1
Scheint nicht zu funktionieren, wenn die Dateien binär sind (zum Beispiel Teile einer Zip-Datei in meinem Fall).
Daniel Lidström
1
@ DanielLidström Es funktioniert auch für Binärdateien mit den richtigen Parametern: Get-Content my.bin -Raw | Set-Content my.bin -NoNewlineändert sich nur mit my.binAusnahme der Zeitstempel. -RawBewahrt alle CR / LF-Bytes auf und -NoNewlineverhindert , dass PowerShell eigene CR / LF-Bytes hinzufügt.
Thomas
62

Nicht verwenden >; es bringt die Zeichenkodierung durcheinander. Verwenden:

Get-Content files.* | Set-Content newfile.file
user2074686
quelle
catist ein Alias ​​für Get-Content.
n0rd
5
@ n0rd Ich denke, es war eher eine Sache "benutze stattdessen die Pipeline".
ksoo
Kann bestätigen. War immer ÿþdas ist , FF FEam Anfang meiner verketteten Datei bei der Verwendung >.
Gpresland
16

In cmdkönnen Sie dies tun:

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

In PowerShell wäre dies:

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

Während die PowerShell-Methode darin besteht, gc zu verwenden , ist das oben Genannte ziemlich schnell, insbesondere bei großen Dateien. Mit dem Schalter kann es auch für Nicht- ASCII- Dateien verwendet /Bwerden.

Manojlds
quelle
3
Für mich führt der Befehl cat mehrere Größenordnungen länger aus als der Befehl cmd / c (der sehr schnell ausgeführt wird). Vielen Dank für den Hinweis auf die Option!
Rob
Dies ist die beste Antwort.
Nicholas DiPiazza
12

Sie können das Cmdlet Add-Content verwenden. Vielleicht ist es etwas schneller als die anderen Lösungen, weil ich den Inhalt der ersten Datei nicht abrufe.

gc .\file2.txt| Add-Content -Path .\file1.txt
mjsr
quelle
Worauf bezieht gcsich?
Octopusgrabbus
gcist ein Alias ​​für Get-Content
MM.
7

Dateien in der Eingabeaufforderung zu konkatieren wäre es

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

PowerShell konvertiert den typeBefehl in Get-Content, was bedeutet, dass bei Verwendung des typeBefehls in PowerShell eine Fehlermeldung angezeigt wird, da für den Get-ContentBefehl ein Komma zwischen den Dateien erforderlich ist. Der gleiche Befehl in PowerShell wäre

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

Wenn Sie die Dateien nach bestimmten Parametern (z. B. Datum und Uhrzeit) sortieren müssen:

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

Ich benutzte:

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

Dies wurde gut angehängt. Ich habe die ASCII-Codierung hinzugefügt, um die Nullzeichen zu entfernen, die Notepad ++ ohne die explizite Codierung angezeigt hat.

Phoenix14830
quelle
2

Sie können so etwas tun wie:

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

Wo >ist ein Alias ​​für "Out-File" und >> ist ein Alias ​​für "Out-File-Append".

vlad-ardelean
quelle
2

Da die meisten anderen Antworten (aufgrund der Rohrleitungen) häufig eine falsche Formatierung aufweisen, ist Folgendes am sichersten:

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

Ich weiß, dass Sie vermeiden wollten, den Inhalt von $ SomeAdditionalFile in eine Variable einzulesen, aber um zum Beispiel Ihre Newline-Formatierung zu speichern, glaube ich nicht, dass es einen richtigen Weg gibt, darauf zu verzichten.

Eine Problemumgehung besteht darin, Ihre $ SomeAdditionalFile Zeile für Zeile zu durchlaufen und diese in Ihre $ YourMasterFile zu leiten. Dies ist jedoch zu ressourcenintensiv.

Kamaradski
quelle
1

So behalten Sie die Codierung und die Zeilenenden bei:

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

Hinweis: AFAIR, dessen Parameter von alten Powershells nicht unterstützt werden (<3? <4?)

Ilyan
quelle
0

Ich denke, der "Powershell-Weg" könnte sein:

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