объединить все текстовые файлы в папке - PullRequest
0 голосов
/ 06 марта 2020

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

s1.txt

Header
1
2
3
4
5
6
7
8

s2.txt

Header
12
22
32
42
52
62
72
82

s3.txt

Header
123
223
323
423
523
623
723
823

Есть два решения

1: простое

copy /b *.txt Combined.txt // It writes header each time also

2: решение с l oop

@echo off
for %%f in (*.txt) do (
   if not exist Combined.txt (
      copy "%%f" Combined.txt
   ) else (
      for /F  "usebackq skip=1 delims=" %%a in ("%%f") do (
         echo %%a>> Combined.txt
      )
   )
)

Но оно не работает должным образом.

Header
1
2
3
4
5
6
7
812  // NEED to start with next line
22
32
42
52
62
72
82
123
223
323
423
523
623
723
823

Есть идеи ?? Также другие решения ???

Ответы [ 2 ]

3 голосов
/ 06 марта 2020

Довольно простым решением является использование команды find , поскольку при необходимости добавляется окончательный перенос строки, поэтому вам не нужно особенно заботиться об этом самостоятельно:

@echo off
rem /* Use a flag-style variable that indicates the first file,
rem    so we know whether or not we have to apply the header: */
set "FIRST=#"
rem // Write to the output file:
> "Combined.txt" (
    rem /* Loop through all input files, with the order is defined by the file system
    rem    (the used pattern also ensures to does not match the output file): */
    for %%I in ("s*.txt") do (
        rem // Query the flag-style variable:
        if defined FIRST (
            rem // This is the first input file, hence return the whole content:
            < "%%~I" find /V ""
        ) else (
            rem // This is not the first input file, hence exclude the header:
            < "%%~I" find /V "Header"
        )
        rem // Clear the flag-style variable here:
        set "FIRST="
    )
)

Если строка заголовка (Header) может встречаться в других строках, кроме заголовка, попробуйте заменить командную строку < "%%~I" find /V "Header" на < "%%~I" (set /P ="" & findstr "^"), хотя это может вызвать проблемы в некоторых Windows версии как findstr могут зависать (см. пост Каковы недокументированные особенности и ограничения команды Windows FINDSTR? ).


Вот подход, основанный на подходе на for /F петлях; отличие от вашего аналогичного подхода заключается в том, что первый файл также обрабатывается for /F l oop, что позволяет также завершить последнюю строку переводом строки в выводе:

@echo off
rem /* Use a flag-style variable that indicates the first file,
rem    so we know whether or not we have to apply the header: */
set "FIRST=#"
rem // Write to the output file:
> "Combined.txt" (
    rem /* Loop through all input files, with the order is defined by the file system
    rem    (the used pattern also ensures to does not match the output file): */
    for %%I in ("s*.txt") do (
        rem // Query the flag-style variable:
        if defined FIRST (
            rem // This is the first input file, hence return the whole content:
            for /F "usebackq delims=" %%L in ("%%~I") do (
                echo(%%L
            )
        ) else (
            rem // This is not the first input file, hence exclude the header:
            for /F "usebackq skip=1 delims=" %%L in ("%%~I") do (
                echo(%%L
            )
        )
        rem // Clear the flag-style variable here:
        set "FIRST="
    )
)

Обратите внимание, что for /F пропускает пустые строки.

0 голосов
/ 06 марта 2020

Этот код предполагает, что заголовок находится в первом упомянутом файле. Если вы используете поддерживаемый компьютер Windows, PowerShell будет доступен. Для этого может потребоваться текущий PowerShell 5.1 или выше.

=== Get-CombinedFile.ps1

$outFilename = 'C:/src/t/Combined.txt'
$files = @('./s1.txt', './s2.txt', './s3.txt')

Set-Location -Path 'C:/src/t'
Get-Content -Path $files[0] -First 1 |
    Out-File -FilePath $outFilename -Encoding ascii
Get-ChildItem -Path $files |
    ForEach-Object {
        Get-Content -Path $_ |
            Select-Object -Skip 1 |
            Out-File -FilePath $outFilename -Encoding ascii -Append
    }

Запустите его в оболочке cmd.exe или в файле .bat.

powershell -NoLogo -NoProfile -File 'C:\src\t\Get-CombinedFile.ps1'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...