Jak połączyć dwa pliki tekstowe w programie PowerShell?

108

Próbuję odtworzyć funkcjonalność catpolecenia w systemie Unix.

Chciałbym uniknąć rozwiązań, w których jawnie wczytuję oba pliki do zmiennych, konkatenuję zmienne razem, a następnie wypisuję połączoną zmienną.

merlin2011
źródło

Odpowiedzi:

170

Możesz po prostu użyć cat example1.txt, example2.txt | sc examples.txt. Z pewnością możesz połączyć więcej niż dwa pliki z tym stylem. Ponadto, jeśli pliki mają podobne nazwy, możesz użyć:

cat example*.txt | sc allexamples.txt

catJest aliasem Get-Content, i scjest aliasem Set-Content.

Uwaga 1 : Uważaj na tę drugą metodę - jeśli spróbujesz wyprowadzić do examples.txt(lub coś podobnego, który pasuje do wzorca), PowerShell wpadnie w nieskończoną pętlę! (Właśnie to przetestowałem).

Uwaga 2 : Wyprowadzanie do pliku z >nie zachowuje kodowania znaków! Dlatego zalecane jest użycie Set-Content( sc).

Smi
źródło
5
Na wypadek, gdyby ktoś chciał iterować pliki za pomocą Get-ChildItems | Konstrukcja Foreach-Object możesz chcieć użyć Add-Content zamiast Set-Content. W przeciwnym razie plik docelowy jest nadpisywany w każdej iteracji.
Jonas,
1
Zauważ, że domyślnie Set-Contentużywa krajowej strony kodowej (np. Windows-1252 dla języka angielskiego). Jeśli pliki źródłowe zawierają inne kodowanie (np. Windows-1251 lub UTF8), należy ustawić prawidłowe kodowanie sc file.txt -Encoding UTF8(liczby takie jak 1251 dla języka rosyjskiego są obsługiwane od wersji 6.2)
Radek Pech
@Jonas Problem Add-Contentpolega na tym, że jeśli uruchomisz polecenie dwa razy, zagregowany plik będzie dwukrotnie dłuższy. Dobry zamiennik to Out-File. Przykład tutaj
Dan Friedman
1
Wydaje się, że nie działa, jeśli pliki są binarne (na przykład części pliku zip w moim przypadku).
Daniel Lidström
1
@ DanielLidström Działa również w przypadku plików binarnych z poprawnymi parametrami: Get-Content my.bin -Raw | Set-Content my.bin -NoNewlinenie zmieni się my.binz wyjątkiem sygnatur czasowych. -Rawzachowuje wszystkie bajty CR / LF, jednocześnie -NoNewlineuniemożliwiając programowi PowerShell dodawanie własnych bajtów CR / LF.
Thomas
62

Nie używać >; psuje kodowanie znaków. Posługiwać się:

Get-Content files.* | Set-Content newfile.file
user2074686
źródło
catjest aliasem dla Get-Content.
n0rd
5
@ n0rd Myślę, że było to bardziej „użyj rurociągu zamiast”.
ksoo
Potwierdzam. Był coraz ÿþktóra jest FF FEna początku mojego połączonego pliku podczas używania >.
gpresland
16

W programie cmdmożesz to zrobić:

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

W PowerShell byłoby to:

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

Podczas gdy sposobem PowerShell byłoby użycie gc , powyższe będzie dość szybkie, szczególnie w przypadku dużych plików. Może być również używany na plikach innych niż ASCII za pomocą /Bprzełącznika.

manojlds
źródło
3
Dla mnie polecenie cat działa o wiele rzędów wielkości dłużej niż polecenie cmd / c (które działa naprawdę szybko); dziękuję za wskazanie opcji!
Rob
To najlepsza odpowiedź.
Nicholas DiPiazza
12

Możesz użyć polecenia cmdlet Add-Content . Może jest trochę szybszy niż inne rozwiązania, bo nie pobieram zawartości pierwszego pliku.

gc .\file2.txt| Add-Content -Path .\file1.txt
mjsr
źródło
Do czego się gcodnosi?
octopusgrabbus
gcjest aliasem dla Get-Content
MM.
8

Byłoby to łączenie plików w wierszu poleceń

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

PowerShell konwertuje typepolecenie na Get-Content, co oznacza, że ​​podczas korzystania z typepolecenia w programie PowerShell wystąpi błąd, ponieważ Get-Contentpolecenie wymaga przecinka oddzielającego pliki. To samo polecenie w PowerShell byłoby

Get-Content file1.txt,file2.txt,file3.txt | Set-Content files.txt
Brian Kimball
źródło
5

Jeśli potrzebujesz uporządkować pliki według określonego parametru (np. Daty i godziny):

gci *.log | sort LastWriteTime | % {$(Get-Content $_)} | Set-Content result.log
Roman O
źródło
3

Użyłem:

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

To dodane grzywny. Dodałem kodowanie ASCII, aby usunąć znaki nul, które Notepad ++ pokazywał bez jawnego kodowania.

Phoenix14830
źródło
2

Możesz zrobić coś takiego:

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

Gdzie >jest aliasem dla „out-file”, a >> jest aliasem dla „out-file -append”.

vlad-ardelean
źródło
2

Ponieważ w większości innych odpowiedzi formatowanie jest często nieprawidłowe (ze względu na orurowanie), najbezpieczniejsze jest wykonanie następujących czynności:

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

Wiem, że chciałeś uniknąć wczytywania zawartości $ SomeAdditionalFile do zmiennej, ale aby zapisać na przykład formatowanie nowej linii, nie sądzę, aby można było to zrobić bez.

Rozwiązaniem byłoby zapętlenie $ SomeAdditionalFile wiersz po wierszu i przekierowanie go do $ YourMasterFile. Jednak jest to nadmiernie wymagające zasoby.

Kamaradski
źródło
1

Aby zachować kodowanie i zakończenia linii:

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

Uwaga: AFAIR, którego parametry nie są obsługiwane przez stare powłoki Powershell (<3? <4?)

Ilyan
źródło
0

Myślę, że „sposób PowerShell” mógłby wyglądać następująco:

set-content destination.log -value (get-content c:\FileToAppend_*.log )
dvjz
źródło