Как объединить два текстовых файла в PowerShell?


108

Я пытаюсь воспроизвести функциональность catкоманды в Unix.

Я бы хотел избежать решений, в которых я явно считываю оба файла в переменные, объединяю переменные вместе, а затем записываю объединенную переменную.

Ответы:


170

Вы можете просто использовать cat example1.txt, example2.txt | sc examples.txt. Вы также можете объединить более двух файлов с этим стилем. Кроме того, если файлы названы одинаково, вы можете использовать:

cat example*.txt | sc allexamples.txt

Это catпсевдоним для Get-Contentи scявляется псевдонимом для Set-Content.

Примечание 1 : будьте осторожны с последним методом - если вы попытаетесь выполнить вывод в examples.txt(или аналогичный, соответствующий шаблону), PowerShell попадет в бесконечный цикл! (Я только что это проверил).

Примечание 2 : при выводе в файл >кодировка символов не сохраняется! Вот почему рекомендуется использовать Set-Content( sc).


5
На всякий случай кто-то захочет перебрать файлы с помощью Get-ChildItems | В конструкции Foreach-Object вы можете использовать Add-Content вместо Set-Content. В противном случае целевой файл перезаписывается на каждой итерации.
Jonas

1
Обратите внимание, что по умолчанию Set-Contentиспользуется национальная кодовая страница (например, Windows-1252 для английского языка). Если исходные файлы содержат другую кодировку (например, Windows-1251 или UTF8), вы должны установить правильную кодировку sc file.txt -Encoding UTF8(числа, такие как 1251 для русского языка, поддерживаются с
Радек Печ

@Jonas Проблема в Add-Contentтом, что если вы запустите команду дважды, агрегированный файл будет вдвое длиннее. Хорошая замена есть Out-File. Пример здесь
Дэн Фридман

1
Кажется, не работает, если файлы являются двоичными (например, части zip-файла в моем случае).
Даниэль Лидстрем,

1
@ DanielLidström Это также работает для двоичных файлов с правильными параметрами: Get-Content my.bin -Raw | Set-Content my.bin -NoNewlineне будет изменяться, my.binкроме отметок времени. -Rawсохраняет любые байты CR / LF, -NoNewlineне позволяя PowerShell добавлять собственные байты CR / LF.
Томас

62

Не использовать >; это портит кодировку символов. Использование:

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

catэто псевдоним для Get-Content.
n0rd 05

5
@ n0rd Я думаю, что это было больше похоже на «используйте конвейер вместо».
ksoo

Могу подтвердить. Получал то, ÿþчто находится FF FEв начале моего объединенного файла при использовании >.
gpresland

16

В cmd, вы можете сделать это:

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

В PowerShell это будет:

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

Хотя в PowerShell можно использовать gc , описанное выше будет довольно быстрым, особенно для больших файлов. И его можно использовать с файлами, отличными от ASCII, с помощью /Bпереключателя.


3
Для меня команда cat выполняется на несколько порядков дольше, чем команда cmd / c (которая выполняется очень быстро); спасибо, что указали на вариант!
Роб

Это лучший ответ.
Николас ДиПиацца

12

Вы можете использовать командлет Add-Content . Возможно, это немного быстрее, чем другие решения, потому что я не получаю содержимое первого файла.

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

К чему gcотносится?
octopusgrabbus

gcэто псевдоним для Get-Content
MM.

8

Чтобы объединить файлы в командной строке, это будет

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

PowerShell преобразует typeкоманду в Get-Content, что означает, что вы получите сообщение об ошибке при использовании typeкоманды в PowerShell, потому что для Get-Contentкоманды требуется запятая, разделяющая файлы. Та же команда в PowerShell будет

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

5

Если вам нужно упорядочить файлы по определенному параметру (например, дате и времени):

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

3

Я использовал:

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

К этому добавлен штраф. Я добавил кодировку ASCII, чтобы удалить нулевые символы, которые Notepad ++ показывал без явной кодировки.


2

Вы можете сделать что-то вроде:

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

Где >псевдоним для "out-file", а >> - псевдоним для "out-file -append".


2

Поскольку большинство других ответов часто имеют неправильное форматирование (из-за конвейера), безопаснее всего сделать следующее:

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

Я знаю, что вы хотели избежать чтения содержимого $ SomeAdditionalFile в переменной, но, чтобы сохранить, например, форматирование новой строки, я не думаю, что есть правильный способ обойтись без этого.

Обходной путь заключается в том, чтобы перебрать ваш $ SomeAdditionalFile построчно и передать его в ваш $ YourMasterFile. Однако это слишком ресурсоемко.


1

Чтобы сохранить кодировку и окончания строк:

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

Примечание. AFAIR, параметры которого не поддерживаются старыми оболочками Powershell (<3? <4?)


0

Я думаю, что "способ PowerShell" может быть таким:

set-content destination.log -value (get-content c:\FileToAppend_*.log )
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.