Як з'єднати два текстові файли в 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. В іншому випадку цільовий файл перезаписується в кожній ітерації.
Йонас

1
Зауважте, що за замовчуванням Set-Contentвикористовується національна кодова сторінка (наприклад, Windows-1252 для англійської мови). Якщо вихідні файли містять інше кодування (наприклад, Windows-1251 або UTF8), ви повинні встановити правильне кодування sc file.txt -Encoding UTF8(такі цифри, як 1251 для російської мови, підтримуються з v6.2)
Radek Pech

@Jonas Проблема Add-Contentполягає в тому, що якщо запустити команду двічі, то зведений файл удвічі довший. Гарна заміна є Out-File. Приклад тут
Dan Friedman

1
Здається, це не працює, якщо файли двійкові (наприклад, частини zipfile у моєму випадку).
Даніель Лідстрем

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

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відноситься?
восьминога граббус

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, параметри якого не підтримуються старими Powershells (<3? <4?)


0

Я думаю, що "спосіб перешкод" може бути:

set-content destination.log -value (get-content c:\FileToAppend_*.log )
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.