Как сначала упорядочить файлы в папке по дате, а затем объединить их содержимое в новый файл? - PullRequest
1 голос
/ 27 января 2020

У меня есть папка с четырьмя-пятью текстовыми файлами.

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

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

Мой процесс сейчас выглядит так:

  1. Заказать файлы в этой папке по дате.
  2. Создайте временный файл и запишите содержимое из отдельных файлов в этот файл.
  3. Выведите временный файл.

In код Я делаю что-то вроде этого:

set temp_concat=%temp_dir%\temp_concat.log
echo %temp_concat%
echo aiu_logs   > %temp_concat%
for /f "delims=" %%? in ('dir /b /o:d %Folder%*') do (
    for /f "delims=" %%K in (%Folder%%%?) do (
        echo  %%K   >>%temp_concat%
    )
)

Приведенный выше код работает, так как мой temp_concat очень большой.

Однако, это занимает намного больше времени, чем ожидалось. Мне нужно подождать около 40 секунд, чтобы объединить три файла в моем случае.

Есть ли лучший способ объединить некоторое количество файлов, но сохранить их в правильном порядке по дате?

Ответы [ 2 ]

1 голос
/ 27 января 2020

Этот пакетный файл использует предложение, опубликованное Sqashman , чтобы использовать FOR l oop для создания строки аргументов для команды COPY , используемой для объединения содержимое файла в один файл в следующем порядке: самый старый измененный файл первым и последний измененный файл последним.

@echo off
setlocal EnableExtensions EnableDelayedExpansion

set "Folder=%~dp0"
if not "%~1" == "" set "Folder=%~1"
set "Folder=%Folder:/=\%"
if not "%Folder:~-1%" == "\" set "Folder=%Folder%\"

set "ResultsFile=%Folder%Results.log"
del "%ResultsFile%" 2>nul
set "Arguments="

for /F "eol=| delims=" %%I in ('dir /A-D-H /B /O:D "%Folder%*" 2^>nul') do if not "%%~fI" == "%~f0" set "Arguments=!Arguments! + "%%I""

if defined Arguments (
    echo aiu_logs>"%ResultsFile%"
    copy /B "%ResultsFile%"%Arguments% "%ResultsFile%" >nul
)

endlocal

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

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

Лучшим решением будет использование следующего пакетного файла:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

set "Folder=%~dp0"
if not "%~1" == "" set "Folder=%~1"
set "Folder=%Folder:/=\%"

pushd "%Folder%" 2>nul
if errorlevel 1 goto EndBatch

set "ResultsFile=Results.log"
del "%ResultsFile%" 2>nul
set "Arguments="

for /F "eol=| delims=" %%I in ('dir /A-D-H /B /O:D * 2^>nul') do if not "%%~fI" == "%~f0" call set "Arguments=%%Arguments%% + "%%I""

if defined Arguments (
    echo aiu_logs>"%ResultsFile%"
    copy /B "%ResultsFile%"%Arguments% "%ResultsFile%" >nul
)

popd
:EndBatch
endlocal

Путь к папке с одним или несколькими восклицательные знаки больше не проблема. Кроме того, имена файлов могут содержать !, поскольку в этом пакетном файле не используется расширение с задержкой, которое немного медленнее, чем первый пакетный файл.

Папка с объединяемыми файлами становится текущей папкой. этот пакетный файл. По этой причине в качестве аргументов в командной строке COPY можно указать больше имен файлов по сравнению с первым пакетным файлом, поскольку имена файлов указаны без пути. Но количество содержимого файла, которое можно объединить с этим пакетным файлом, тем не менее ограничено максимальной длиной командной строки Windows и максимальной длиной значения переменной среды.

Для понимания используемых команд и как они работают, откройте окно командной строки , выполните там следующие команды и очень внимательно прочитайте все страницы справки, отображаемые для каждой команды.

  • call /?
  • copy /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • popd /?
  • pushd /?
  • set /?
  • setlocal /?

Прочтите также статью Microsoft о Использование операторов перенаправления команд для объяснения > и 2>nul. Оператор перенаправления > должен быть экранирован с помощью символа вставки ^ в FOR командной строке, чтобы интерпретироваться как литеральный символ, когда интерпретатор команд Windows обрабатывает эту командную строку перед выполнением команды FOR который выполняет встроенную командную строку dir в отдельном командном процессе, запущенном в фоновом режиме с %ComSpec% /c и командной строкой DIR между двумя ', добавленными в качестве дополнительных аргументов.

0 голосов
/ 27 января 2020

Второй FOR /F не содержит команду. Он содержит имя файла. Я не проверял это, но возможно:

set temp_concat=%temp_dir%\temp_concat.log
echo %temp_concat%
echo aiu_logs   > "%temp_concat%"
for /f "delims=" %%? in ('dir /b /o:d "%Folder%"') do (
    if not "%%~f?" == "%~f0" (
        type %%? >>"%temp_concat%"
    )
)

Это объединит все файлы в каталоге "% Folder%". Пути должны быть заключены в кавычки, если в них есть специальные символы.

...