Come concatenare due file di testo in PowerShell?


108

Sto cercando di replicare la funzionalità del catcomando in Unix.

Vorrei evitare soluzioni in cui leggo esplicitamente entrambi i file in variabili, concateno le variabili insieme e quindi scrivo la variabile concatenata.

Risposte:


170

Puoi semplicemente usare cat example1.txt, example2.txt | sc examples.txt. Puoi sicuramente concatenare anche più di due file con questo stile. Inoltre, se i file hanno nomi simili, puoi usare:

cat example*.txt | sc allexamples.txt

Il catè un alias per Get-Content, ed scè un alias per Set-Content.

Nota 1 : fai attenzione con quest'ultimo metodo: se provi a eseguire l'output in examples.txt(o simile che corrisponde al modello), PowerShell entrerà in un ciclo infinito! (L'ho appena testato).

Nota 2 : l'output in un file con >non preserva la codifica dei caratteri! Questo è il motivo per cui si consiglia di utilizzare Set-Content( sc).


5
Nel caso in cui qualcuno volesse iterare sui file con Get-ChildItems | Foreach-Object costrutto potresti voler usare Add-Content invece di Set-Content. In caso contrario, il file di destinazione viene sovrascritto ad ogni iterazione.
Jonas

1
Si noti che per impostazione predefinita Set-Contentutilizza la code page nazionale (ad esempio Windows-1252 per l'inglese). Se i file sorgente contengono altra codifica (ad esempio Windows-1251 o UTF8), è necessario impostare la codifica corretta sc file.txt -Encoding UTF8(numeri come 1251 per il russo sono supportati dalla v6.2)
Radek Pech

@ Jonas Il problema Add-Contentè che se esegui il comando due volte, il file aggregato è lungo il doppio. Un buon sostituto è Out-File. Esempio qui
Dan Friedman

1
Non sembra funzionare se i file sono binari (ad esempio, parti di un file zip nel mio caso).
Daniel Lidström

1
@ DanielLidström Funziona anche per binari con i parametri corretti: Get-Content my.bin -Raw | Set-Content my.bin -NoNewlinenon cambierà my.bintranne i timestamp. -Rawconserva tutti i byte CR / LF, mentre -NoNewlineimpedisce a PowerShell di aggiungere i propri byte CR / LF.
Thomas,

62

Non utilizzare >; rovina la codifica dei caratteri. Uso:

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

catè un alias per Get-Content.
n0

5
@ n0rd Penso che fosse più una cosa "usa la pipeline invece".
ksoo

Posso confermare. Stavo ottenendo ÿþche è FF FEall'inizio del mio file concatenato durante l'utilizzo >.
gpresland

16

In cmd, puoi farlo:

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

In PowerShell questo sarebbe:

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

Mentre il modo in cui PowerShell sarebbe usare gc , quanto sopra sarà abbastanza veloce, specialmente per file di grandi dimensioni. E può essere utilizzato anche su file non ASCII utilizzando l' /Binterruttore.


3
Per me il comando cat esegue più ordini di grandezza più a lungo del comando cmd / c (che viene eseguito molto velocemente); grazie per aver segnalato l'opzione!
Rob il

Questa è la migliore risposta.
Nicholas DiPiazza

12

È possibile utilizzare il cmdlet Add-Content . Forse è un po 'più veloce delle altre soluzioni, perché non recupero il contenuto del primo file.

gc .\file2.txt| Add-Content -Path .\file1.txt

A cosa si gcriferisce?
octopusgrabbus

gcè un alias per Get-Content
MM.

8

Per concatenare i file nel prompt dei comandi sarebbe

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

PowerShell converte il typecomando in Get-Content, il che significa che riceverai un errore quando usi il typecomando in PowerShell perché il Get-Contentcomando richiede una virgola che separa i file. Lo stesso comando in PowerShell sarebbe

Get-Content file1.txt,file2.txt,file3.txt | Set-Content files.txt

5

Se è necessario ordinare i file in base a un parametro specifico (es. Data e ora):

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

3

Ero solito:

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

Questo aggiunto bene. Ho aggiunto la codifica ASCII per rimuovere i caratteri nul che Notepad ++ mostrava senza la codifica esplicita.


2

Puoi fare qualcosa come:

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

Dove >è un alias per "out-file" e >> è un alias per "out-file -append".


2

Poiché la maggior parte delle altre risposte spesso ha una formattazione errata (a causa delle tubazioni), la cosa più sicura da fare è la seguente:

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

So che volevi evitare di leggere il contenuto di $ SomeAdditionalFile in una variabile, ma per salvare ad esempio la formattazione di nuova riga non penso che ci sia un modo corretto per farne a meno.

Una soluzione alternativa potrebbe essere quella di scorrere il tuo $ SomeAdditionalFile riga per riga e collegarlo al tuo $ YourMasterFile. Tuttavia questo è eccessivamente dispendioso in termini di risorse.


1

Per mantenere la codifica e le terminazioni di riga:

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

Nota: AFAIR, i cui parametri non sono supportati dai vecchi Powershells (<3? <4?)


0

Penso che il "modo powershell" potrebbe essere:

set-content destination.log -value (get-content c:\FileToAppend_*.log )
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.