как объединить содержимое всех файлов в каталоге по порядку имен?

#powershell #concatenation

Вопрос:

У меня есть куча текстовых файлов, которые мне нужно объединить в 1 строку:

введите описание изображения здесь

Конечным результатом является объединение содержимого 20211026_113900.sql 20211027_083900.sql 20211027_093900.sql

Как мы объединяем содержимое файлов в алфавитном порядке?

20211026_113900.sql

выберите имя из mytable1 ПЕРЕЙТИ

20211027_083900.sql

выберите имя из mytable2 ПЕРЕЙТИ

20211027_093900.sql

выберите имя из mytable3 GO

Конечный результат, которого я ожидаю, таков:

выберите имя из mytable1 ПЕРЕЙДИТЕ выберите имя из mytable2 ПЕРЕЙДИТЕ выберите имя из mytable3 ПЕРЕЙДИТЕ

Ответ №1:

Перечислите все файлы с Get-ChildItem :

 $files = Get-ChildItem -Path pathtoScripts -File -Filter *.sql 
 

Поставщик файловой системы уже возвращает их в отсортированном порядке, но вы можете явно отсортировать их по имени, используя Sort-Object для удобства, если это вам удобнее:

 $files = $files |Sort-Object -Property Name
 

Наконец, используйте Get-Content -Raw для считывания содержимого файла в память и используйте -join оператор для их объединения:

 $concatenated = @(
    $files |Get-Content -Raw
) -join [Environment]::NewLine
 

$concatenated теперь содержит одну многострочную строку с содержимым всех *.sql файлов, разделенных новыми строками

Замените [Environment]::NewLine на ' ' , чтобы объединить их в той же строке, что и предыдущий файл, или используйте -join в одинарном режиме:

 $concatenated = -join @(
    $files |Get-Content -Raw
)
 

Комментарии:

1. Красиво сделано («если вам так будет удобнее» — приятный штрих :). Что касается одинарных -join решение / объединение с новой строки: учитывая, что -Raw возвращает файла пустую строку, и это текстовые файлы обычно имеют пустую строку, унарный -join , вероятно, в результате никакой контент на одной линии, и, наоборот, вхождение с новой строки, вероятно, приведет к пустой строке между содержимым соответствующих файлов. Что-то подобное ($files |Get-Content -Raw).TrimEnd("`r`n") -join [Environment]::NewLine привело бы к предсказуемому разделению.

2. Из любопытства: Вы используете @(...) по концептуальным соображениям, чтобы было ясно, что LHS -join -это массив ? ( -join также принимает скалярный LHS, что соответственно приводит к отказу от операции).

3. @mklement0 Это просто еще один случай, когда я пытаюсь тонко выразить намерение — мне все равно нужно создать подвыражение (чтобы я не хотел хранить содержимое файла в переменной), и выбор @(...) здесь кажется уместным — это сигнализирует о том, что мы делаем -join , потому что мы ожидаем множество файлов 🙂