1

Тема: Копирование файлов из одной папки в другую по дате

Всем доброго. Связисты озадачили. Есть комп с Windows XP, подключен к АТС, с которой на комп складируются логи звонков. В прилагаемой к АТС софтине есть настройка ведения логов помесячно и посуточно, папка сбора не меняется. Связистам нужно, чтобы логи велись посуточно, но складывались в папку с месяцем ведения, например, в папке 12.2010 должны лежать все логи за декабрь. Думал всё сделать батником, так не могу отфильтровать по дате. В исходной папке хранятся логи не только звонков, но и ещё всякая ерунда, наверно ещё и по имени отбор нужен. Я не программист, а админ. Так что если можно, поподробнее и с комментариями к коду

2

Re: Копирование файлов из одной папки в другую по дате

Недавно делал подобную задачу - перемещение записей с камер в папки архива по датам, а также удаление старых в соответствии с лимитом веса архива.
Язык JScript. Предлагаю ознакомиться для начала:

/***********************************************************************************************************************
* avi_mover.js
* jite, 2010-11-24
* 
* Переносит avi-файлы из папки записи sInFoldername в sNewPath\Камера\Дата\<ВремяС__ВремяПо>
* Ошибки исполнения пишет в лог sLogFilename
* Имеющиеся одноименные файлы перезаписывает (отмечает в логе)
* 
* Положить скрипт рядом с папками камер "192.168.1..." 
* Запускается без параметров - все переменные указываются в скрипте. 
***********************************************************************************************************************/
var sInFoldername = "MotionRecordingFile"; // папка-скрипта\192.*\она-здесь
var sNewPath = "e:\\Cameras"; //Папка архива, без слэша на конце
var sLogFilename = "err_log.txt"; //Если имя без пути - лог пишется в папку со скриптом
var nMultipl = 1024 * 1024 * 1024; //Байт в гигабайте
//Ограничение общего веса файлов в папках sInFoldername и sArcFoldername, b * mult = GB
var nSizeLimit_def = 65 * nMultipl;
//Имя файла содержащего значение максимального допустимого веса файлов для 1 камеры
var sSizeLimitFilename = "SizeLimit.txt";
//Формат представления даты задается в sGetDateString()
//Формат представления времени - в sGetTimeString() и sGetTimeFromFile()

var sDL = "_"; //Разделитель
var sToday = sGetDateString(new Date()); //Сегодня - строкой
var oFS = new ActiveXObject("Scripting.FileSystemObject");
var sCamsfolderWithSlash = WScript.ScriptFullName.substr(0, WScript.ScriptFullName.length - WScript.ScriptName.length);
//sCamsfolderWithSlash = "D:\\00\\(Tmd)\\zcams_test\\"; //DEBUG
if (sLogFilename.indexOf("\\") == -1) //Если имя без пути
  sLogFilename = sCamsfolderWithSlash + sLogFilename;
var oLog;
if (!oFS.FolderExists(sNewPath))
{
  var sMsg = "Не найдено папки архива '" + sNewPath + "'";
  WScript.Echo(sMsg);
  LogWrite(sMsg);
  WScript.Quit(2);
}
//Ищем папки камер
var reCamFolder = /^\d{3}\./gi;
var aCamFolders = aGetArrayOfFiles(oFS.GetFolder(sCamsfolderWithSlash), reCamFolder, false, true);

if (aCamFolders.length == 0)
{
  var sMsg = "Не найдено ни одной папки с видеозаписями!";
  WScript.Echo(sMsg);
  LogWrite(sMsg);
  WScript.Quit(2);
}
//--- 1) Перенос файлов из sInFoldername в  sArcFoldername
//Для каждой камеры
for ( var i = 0; i < aCamFolders.length; i++) //Для записей каждой камеры
{
  var sCamFolder_In = aCamFolders[i].Path + "\\" + sInFoldername;
  var sCamFolder_Arc = sNewPath + "\\" + aCamFolders[i].Name;
//При отсутствии исходной папки записей - пропускаем камеру, с записью в лог
  if (!bProvideFolder(sCamFolder_In, false, "записей")) 
    continue;
  var oCamFolder_In = oFS.GetFolder(sCamFolder_In);
//При невозможности создать архивную - пропускаем камеру, с записью в лог
  if (!bProvideFolder(sCamFolder_Arc, true, "архива записей")) 
    continue;
  var oCamFolder_Arc = oFS.GetFolder(sCamFolder_Arc);

  //Собираем файлы в папке
  var reAviFile = /\.avi$/gi;
  var aFiles = aGetArrayOfFiles(oCamFolder_In, reAviFile, true, false);
  var oRecords = new Object();
  //Отбираем подходящие на перемещение 
  for ( var j = 0; j < aFiles.length; j++)
  {
    var sFileDate = sGetDateString(aFiles[j].DateLastModified);
    if (sFileDate !== sToday)
      Collect(oRecords, sFileDate, aFiles[j]); //Если дата не равна сегодняшней, пишем в oRecords
  }
  if (oRecords.length == 0) //Перемещать нечего - пропускаем
    continue;
  for ( var sDate in oRecords)
  {
    var sDstFolder = oCamFolder_Arc.Path + "\\" + sDate;
    if (!bProvideFolder(sDstFolder, true, "архива записей"))
      continue;
    for ( var k = 0; k < oRecords[sDate].length; k++)
    {
      var sNewFilename = sGetTimeFromFile(oRecords[sDate][k].Name);
      try
      {
        if (sNewFilename !== "") //Если правильно вычленили время начала, добавляем разделитель
          sNewFilename += sDL + sDL;
        else
          LogWrite("Неожиданное имя файла: '" + oRecords[sDate][k].Path + "'");
        sNewFilename = sDstFolder + "\\" + sNewFilename + sGetTimeString(oRecords[sDate][k].DateLastModified) + ".avi";
        if (oFS.FileExists(sNewFilename)) //Если нашли с таким же именем
        {
          LogWrite("Замена имеющегося файла '" + sNewFilename + "'");
          oFS.DeleteFile(sNewFilename, true);
        }
        oRecords[sDate][k].Move(sNewFilename);
      }
      catch(e)
      {
        LogWrite("Ошибка переноса файла '" + oRecords[sDate][k].Path + "' в папку '" + sDstFolder + "' " + e.number + 
                 ": " + e.message);
      }
    } //Для каждого файла
  } //Для каждой даты
} //Для каждой камеры

//--- 2) Удаление папок из sArcFoldername для обеспечения общего веса не более установленного
//Для каждой камеры
for ( var i = 0; i < aCamFolders.length; i++) //Для записей каждой камеры
{
  var nSizeLimit = nSizeLimit_def; //default
  var sSizeLimitFile = aCamFolders[i].Path + "\\" + sSizeLimitFilename;
  var nRes = nGetSizeLimit(sSizeLimitFile, oFS);
  if (nRes > 0)
    nSizeLimit = nRes * nMultipl;
  var sCamFolder_In = aCamFolders[i].Path + "\\" + sInFoldername; //Текущая папка записи
  if (!oFS.FolderExists(sCamFolder_In)) //Папки нет
    continue; //Не сообщаем, т.к. о возможных проблемах сообщалось в ч1
  var oCamFolder_In = oFS.GetFolder(sCamFolder_In);
  var oFD_In = oGetFD(oCamFolder_In); //Добыто
  var sCamFolder_Arc = sNewPath + "\\" + aCamFolders[i].Name; //Текущая архивная
  if (!bProvideFolder(sCamFolder_Arc, true, "архива записей")) //Не создалась? - пропускаем камеру и пишем в лог
    continue;
  var oCamFolder_Arc = oFS.GetFolder(sCamFolder_Arc);
  var aArcFolders = aGetArrayOfFiles(oCamFolder_Arc, reGetDateRE(), false, true);
  var aFD_Arc = new Array();
  for ( var j = 0; j < aArcFolders.length; j++)
    aFD_Arc.push(oGetFD(aArcFolders[j]));
  aFD_Arc.sort(nSortFD);

  //Подсчет размера до превышения разрешенного
  var aFD_Delete = null; //Массив для удаления
  var nSizeSum = oFD_In.Size;
  if (nSizeSum > nSizeLimit) //Если записанного недавно так много, что архивы не влезают
    aFD_Delete = aFD_Arc; //К удалению - все архивы
  else
  { //Иначе проверяем объем архивов по объему
    var nIdx = 0; //Индекс, начиная с которого все папки в aFD_Arc следует удалить, т.к. не влезают в лимиты
    while (nIdx < aFD_Arc.length)
    {
      nSizeSum += aFD_Arc[nIdx].Size;
      if (nSizeSum > nSizeLimit)
      {
        aFD_Delete = aFD_Arc.slice(nIdx); //Кусок массива, начиная с индекса nIdx
        break;
      }
      nIdx++;
    }
  }

  if (aFD_Delete !== null) //Если есть что удалять
  {
    for ( var j = 0; j < aFD_Delete.length; j++)
    {
      try
      {
        aFD_Delete[j].Link.Delete(true);
      }
      catch(e)
      {
        LogWrite("Ошибка удаления папки '" + aFD_Delete[j].Link.Path + "' " + e.number + ": " + e.message);
      }
    }
  } //Есть что удалять
} //Для каждой камеры

//=== functions ========================================================================================================
/** Пишет в лог oLog сообщение sMsg, открывает лог если он еще не открыт
 */
function LogWrite(sMsg)
{
  if (typeof (oLog) == "undefined") //Если не открыт, открываем (oLog - глобальная переменная)
  {
    oLog = new Log(sLogFilename);
    if (oLog.nError !== 0)
    {
      WScript.Echo("Не удалось открыть лог. " + oLog.sLogName + " " + oLog.nError + " " + oLog.sErrorMsg);
      WScript.Quit(1);
    }
  } //Если не открыт, открываем
  oLog.WriteLine(sMsg);
}

/** Возвращает массив папок/файлов в папке oFolder (в подпапках не ищет) 
 * @param oFolder - FileSystemObject
 * @param reNameMask - RegExp соответствия имени файла/папки (включая расширение) для включения в результаты поиска
 * @param bGetFiles, bGetFolders - включать ли в результаты поиска имена файлов, папок, соответственно
 * @return - FileSystemObject
 */
function aGetArrayOfFiles(oFolder, reNameMask, bGetFiles, bGetFolders)
{
  var aOut = new Array();
  var enFiles;
  if (bGetFolders) //Собираем папки
  {
    enFiles = new Enumerator(oFolder.SubFolders);
    Work(enFiles);
  }
  if (bGetFiles) //Собираем файлы
  {
    enFiles = new Enumerator(oFolder.Files);
    Work(enFiles);
  }
  //Общий код
  function Work(oEnum)
  {
    for (; !oEnum.atEnd(); oEnum.moveNext())
    {
      if (reNameMask.test(oEnum.item().Name))
        aOut.push(oEnum.item());
      reNameMask.test(""); //FIXED Лишний вызов, убирающий глюк возвращения неправильного false после true
    }
  }
  return aOut;
}

/** Обеспечивает или только проверяет наличие папки sFolderName, при неудаче возвращает false
 * @param sFullFolderName - полный путь к папке
 * @param bDoCreate - пытаться ли создать папку?
 * @param sErrMsg - сообщение в лог при неудаче
 * @return boolean - Есть ли в результате папка?
 */
function bProvideFolder(sFullFolderName, bDoCreate, sErrMsgPart)
{
  if (!oFS.FolderExists(sFullFolderName)) //Если не нашли - пишем в лог и - false
    if (bDoCreate) //Попытаемся создать
    {
      try
      {
        oFS.CreateFolder(sFullFolderName);
      }
      catch(e)
      {
        LogWrite("Ошибка создания папки '" + sFullFolderName + "' " + e.number + ": " + e.message);
      }
      if (oFS.FolderExists(sFullFolderName))
        return true;
      else
      {
        LogWrite("Не удалось создать папку " + sErrMsgPart + " '" + sFullFolderName + "'");
        return false;
      }
    }
    else
    { //Не пытаемся создать
      LogWrite("Папка " + sErrMsgPart + " '" + sFullFolderName + "' не найдена.");
      return false;
    }
  else
    return true;
}

/** Возвращает строкой определенного формата дату dDate.
 */
function sGetDateString(dDate)
{
  var sWeekDays = ["Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"];
  dDate = new Date(dDate); //FIXED Не признает переданную в функцию дату - датой. Убеждаем в обратном :)
  return sLeadingZeros(dDate.getDate()) + "." + sLeadingZeros(dDate.getMonth() + 1) + "." + dDate.getFullYear() + sDL
    + sWeekDays[dDate.getDay()]; //ДД.ММ.ГГГГ_ДН
}

/** Возвращает регулярное выражение для поиска строк, выдаваемых sGetDateString()
 * Вынесено в отдельную функцию для удобства совместной правки с sGetDateString()
 */
function reGetDateRE()
{
  return /^(\d{2}\.){2}\d{2}.*$/gi;
}

/** Возвращает строкой формата hh-mm_ss дату dDate
 */
function sGetTimeString(dDate)
{
  dDate = new Date(dDate); //FIXED Не признает переданную в функцию дату - датой. Убеждаем в обратном :)
  return sLeadingZeros(dDate.getHours()) + "-" + sLeadingZeros(dDate.getMinutes()) + sDL + 
    sLeadingZeros(dDate.getSeconds()); //hh-mm_ss
}

/** Возвращает строкой формата hh-mm_ss время из имени файла  
 */
function sGetTimeFromFile(sFilename)
{
  var reFilenameAsDateStamp = /^\d{8}(\d{2})(\d{2})(\d{2})\.avi$/gi; //Исходное имя файла
  var bRes = reFilenameAsDateStamp.test(sFilename);
  reFilenameAsDateStamp.test(""); //FIXED Лишний вызов, убирающий глюк возвращения неправильного false после true
  if (bRes)
    return sFilename.replace(reFilenameAsDateStamp, "$1-$2_$3");
  else
    return "";
}

/** Дополняет текстовое представление obj (предполагается число) нулями до длины nOutLength. Минус выносится вперед
 */
function sLeadingZeros(obj, nOutLength)
{
  if (typeof (obj) == "undefined")
    return(null);
  if (typeof (nOutLength) !== "number")
    nOutLength = 2; //Выходная длина строки по ум.
  var sObj = obj.toString(); //Строковое представление объекта
  if (sObj.length < nOutLength) //Если надо удлинять
  {
    var res = "";
    if (sObj.charAt(0) == "-") //Если отрицательное
    {
      res = "-";
      sObj = sObj.substr(1);
    }
    var nZeros = nOutLength - res.length - sObj.length; //Число доп. нулей
    for ( var i = 0; i < nZeros; i++)
      res += "0";
    res += sObj;
    return(res);
  }
  else
    //Удлинять не надо
    return(sObj); //Возвращаем строковое представление
}

/** Добавляет в oBj значения oVal, используя sProp как свойства, каждое из которых содержит массив элементов oVal
 */
function Collect(oBj, sProp, oVal)
{
  if (!(sProp in oBj))
    oBj[sProp] = new Array();
  oBj[sProp].push(oVal);
}

/** Возвращает число, содержащееся в 1-й строке файла sFilename. При неудаче возвращает 0
 */
function nGetSizeLimit(sFilename, oFS)
{
  if (!oFS.FileExists(sFilename)) //Файла нет
    return 0;
  var oFile = oOpenForRead(sFilename, oFS);
  if (oFile == null) //Не получилось открыть
    return 0;
  var sFirstLine = "";
  try
  {
    sFirstLine = oFile.ReadLine();
    var nOut = parseInt(sFirstLine, 10);
    if (isNaN(nOut))
      nOut = 0;
    return nOut;
  }
  catch(e)
  {
    //WScript.Echo("Ошибка при чтении файла '" + sFilename + "': " + e.number + ": " + e.message);
    return 0; //Нечего читать или не распознали
  }
}

/** Открывает файл sFilename для чтения
 */
function oOpenForRead(sFilename, oFS)
{
  var nForReading = 1;
  var bCreate = false;
  var oFile;
  try
  {
    oFile = oFS.OpenTextFile(sFilename, nForReading, bCreate); //Открываем как ANSI
  }
  catch(e)
  {
    return null;
  }
  return oFile;
}

/** Возвращает данные папки sFolder в виде объекта FolderData. При неудаче - null
 */
function oGetFD(oFolder)
{
  var aFiles = aGetArrayOfFiles(oFolder, /.+/gi, true, false);
  var nSum = 0;
  var dOldestFileDate = new Date(); //Дата старейшего файла в папке
  for ( var j = 0; j < aFiles.length; j++)
  {
    var oParse = parseInt(aFiles[j].Size, 10);
    if (!isNaN(oParse))
      nSum += oParse;
    else
      LogWrite("oGetFD(). Подсчет веса. '" + aFiles[j].Path + "' Неожиданный размер файла '" + aFiles[j].Size + "'");
    var dCurrentFileDate = aFiles[j].DateLastModified;
    if (dCurrentFileDate < dOldestFileDate)
      dOldestFileDate = dCurrentFileDate;
  }
  return new FolderData(oFolder, nSum, dOldestFileDate);
}

/** Класс данных о папке: oFS-ссылка и суммарный вес файлов в байтах (в подпапках не смотрит).
 */
function FolderData(oFolder, nSize, dDate)
{
  this.Link = oFolder;
  this.Size = nSize;
  this.Date = dDate;
}

/** Функция для sort() массива элементов класса FolderData по дате (от новых к старым)
 */
function nSortFD(oBj1, oBj2)
{
  return oBj2.Date - oBj1.Date;
}

/** Класс работы с логом -----------------------------------------------------------------------------------------------
 * @param sFileName - имя файла лога
 * @param bRewrite - перезаписывать или добавлять?
 */
function Log(sFileName, bRewrite)
{
  this.sLogName = (sFileName.indexOf("\\") === -1) ? //Если не содержит слэшей (т.е. без пути)
  //+ путь к папке скрипта
    WScript.ScriptFullName.substring(0, WScript.ScriptFullName.length - WScript.ScriptName.length) + sFileName : 
    sFileName; //Иначе просто оставляем как есть
  var oFS = new ActiveXObject("Scripting.FileSystemObject");
  this.bCreateIfNotExist = true; //Создавать, если не существует
  this.nOpenAs = 0; // 0 ascii, -1 unicode, -2  system default
  this.nIOMode = 8; //По ум. дописывать лог
  if (typeof (bRewrite) === "boolean" && bRewrite) //Если не опущено при вызове И true
    this.nIOMode = 2; //Перезаписать лог
  this.nError = 1;
  this.sErrorMsg = "Лог еще не открыт";
  // -2146823281 'undefined' -  есть null или не является объектом        --> попытка писать в не окрытый файл
  // -2146828197 Объектная переменная или переменная блока With не задана --> попытка писать в закрытый файл
  // -2146828218 Разрешение отклонено                   --> попытка открыть файл RO или с недостаточными правами доступа
  try
  {
    this.oLog = oFS.OpenTextFile(this.sLogName, this.nIOMode, this.bCreateIfNotExist, this.nOpenAs);
    this.nError = 0;
    this.sErrorMsg = "";
  }
  catch(e)
  {
    this.nError = e.number;
    this.sErrorMsg = e.message;
  }

  //--- Методы

  this.Open = function()
  {
    try
    {
      this.oLog = oFS.OpenTextFile(this.sLogName, this.nIOMode, this.bCreateIfNotExist, this.nOpenAs);
      this.nError = 0;
      this.sErrorMsg = "";
    }
    catch(e)
    {
      this.nError = e.number;
      this.sErrorMsg = e.message;
    }
  };

  this.Write = function(sTr)
  {
    if (typeof (sTr) == "undefined")
      sTr = "";
    try
    {
      this.oLog.Write((new Date()).toLocaleString() + " " + sTr);
      this.nError = 0;
      this.sErrorMsg = "";
    }
    catch(e)
    {
      this.nError = e.number;
      this.sErrorMsg = e.message;
    }
  };

  this.WriteLine = function(sTr)
  {
    if (typeof (sTr) == "undefined")
      sTr = "";
    this.Write(sTr + "\r\n");
  };

  this.Close = function()
  {
    try
    {
      this.oLog.Close();
      this.nError = 0;
      this.sErrorMsg = "";
    }
    catch(e)
    {
      this.nError = e.number;
      this.sErrorMsg = e.message;
    }
  };
} //Log()

//=== DEBUG_STUFF ======================================================================================================

/** Возвращает строку рекурсивного описания содержимого объекта oBj ----------------------------------------------------
 * @param oBj - исследуемый объект
 * @param sParentName - имя объекта, произвольное, по сути комментарий (можно опустить)
 * @param nEsting - максимальный уровень вложенности объектов/значений (можно опустить)
 */
function vardump(oBj, sParentName, nEsting)
{
  var nEsting_max = 20; //Максимальный исследуемый уровень вложенности
  var nPadding = 2; //Структурный отступ в пробелах, сдвига потомков отн. родителей
  if (typeof (sParentName) == "undefined") //default
    sParentName = "";
  if (typeof (nEsting) != "number") //default
    nEsting = nEsting_max;
  var sRes = "";
  if (nEsting >= 0)
  {
    var nGap = nPadding * (nEsting_max - nEsting);
    for ( var i = 0; i < nGap; i++)
      sRes += " ";
    sRes += sParentName + (sParentName == "" ? "" : " ") + "(" + typeof (oBj) + ")=>" + oBj + "<\r\n"; 
    if (typeof (oBj) == "object")
      for ( var oEl in oBj)
      {
        var sObjName = sParentName; //Имя потомка
        if (sObjName != "") //Если есть что отделять, отделяем точкой
          sObjName += ".";
        sObjName += oEl;
        sRes += arguments.callee(oBj[oEl], sObjName, nEsting - 1);
      }
  }
  else
    sRes = sParentName + " ! Nesting limit !\r\n";
  return(sRes);
} //vardump

/**
 * Echo-обертка для vardump()
 */
function vard()
{
  WScript.Echo(vardump.apply(null, arguments));
}

3

Re: Копирование файлов из одной папки в другую по дате

Я думаю, на Autohotkey код мог быть гораздо короче.

В прилагаемой к АТС софтине есть настройка ведения логов помесячно и посуточно, папка сбора не меняется. Связистам нужно, чтобы логи велись посуточно, но складывались в папку с месяцем ведения, например, в папке 12.2010 должны лежать все логи за декабрь.
... В исходной папке хранятся логи не только звонков, но и ещё всякая ерунда, наверно ещё и по имени отбор нужен.

Значит, каждые сутки в одной и той же папке создаётся новый файл с характерным именем? А требуется разложить их по папка в зависимости от имени файла?
Приведите примеры названия файлов звонков и названия файлов "всякой ерунды".

4

Re: Копирование файлов из одной папки в другую по дате

ypppu пишет:

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

Нет, разложить их нужно по дате создания

ypppu пишет:

Приведите примеры названия файлов звонков и названия файлов "всякой ерунды".

Названия файлов звонков начинаются с цифр 37 либо 38, в зависимости от используемой в данный момент АТС. Остальные файлы имеют вид QAN119.txt, TDO409.txt и т.д., первые три латинские буквы и три цифры.
jite, большое спасибо, но тут что-то слишком закрученный сюжет. Я думал это гораздо проще будет

5 (изменено: VitAliS, 2010-12-27 10:04:16)

Re: Копирование файлов из одной папки в другую по дате

попробуйте так:

@echo off
set sourcedir=папка где лежат файлы
set destdir=папка куда копировать
for /F "usebackq tokens=1-5,* delims=. " %%i in (`dir %sourcedir%\ /O:D /A:-D^|findstr /R "[^:]3[78].*\.txt$"`) do (
if not exist %destdir%\%%j.%%k md %destdir%\%%j.%%k
copy /y %sourcedir%\%%n %destdir%\%%j.%%k\
)

если нужно перемещать, а не копировать, то вместо copy можно указать move

6

Re: Копирование файлов из одной папки в другую по дате

хотя думаю вот так будет правильнее:

@echo off
set sourcedir=папка где лежат файлы
set destdir=папка куда копировать
for /F "usebackq tokens=1-5,* delims=. " %%i in (`dir %sourcedir%\3*.txt /O:D /A:-D^|findstr /R "3[78].*\.txt$"`) do (
if not exist %destdir%\%%j.%%k md %destdir%\%%j.%%k
copy /y %sourcedir%\%%n %destdir%\%%j.%%k\
)

7

Re: Копирование файлов из одной папки в другую по дате

VitAliS, а можно с комментариями? И на каком языке это всё выполнить?

8

Re: Копирование файлов из одной папки в другую по дате

neperap пишет:

VitAliS, а можно с комментариями? И на каком языке это всё выполнить?

Можно
Это батник обычный.

Ну теперь комментарии:
Сначала определяем директории откуда (sourcedir) и куда (destdir) копируем файлы
Потом в цикле разбираем вывод команды dir отфильтрованный по конвейеру findstr'ом
Если я правильно понял, то файлы с логами звонко представляютиз себя текстовые файлы вида 37*.txt и 38*.txt
то команда:

dir %sourcedir%\3*.txt /O:D /A:-D^|findstr /R "\<3[78].*\.txt$"

нам как-раз и выдаст список подходящих под описание файлов, отсортированных по времени
разбирая вывод этой команды мы получаем в переменную %n имена файлов, а в переменные %j и %k месяц и год их создания
в папке назначения проверяем наличие папки вида месяц.год, и если ее нет, то создаем
после этого копируем (перемещаем) в нее файл

вот собственно и всё
ps: пока писал пост, нашел неточность у себя в предыдущем посте, поэтому написал здесь findstr /R "\<3[78].*\.txt$"

9 (изменено: neperap, 2010-12-28 07:59:32)

Re: Копирование файлов из одной папки в другую по дате

VitAliS, большое спасибо. Задача опять изменилась и упростилась. Нужно копировать ВСЕ файлы из папки сбора, без разбора имени. Остаётся только отбор по дате.

10

Re: Копирование файлов из одной папки в другую по дате

Убрал условие

|findstr /R "\<3[78].*\.txt$"

, вроде бы копирует правильно, но в папке назначения создаются папки с названиями
в.устройстве
папок.10
файлов.69
И ещё, файлы при повторном запуске батника заменяются. Можно этот момент исключить?

11 (изменено: VitAliS, 2010-12-28 10:03:21)

Re: Копирование файлов из одной папки в другую по дате

вывод dir %sourcedir%\ /O:D /A:-D
сюда, пожалуйста, предоставьте

И ещё, файлы при повторном запуске батника заменяются. Можно этот момент исключить?

ну правильно, там же copy /y написано, т.е. перезаписывать
если нужно чтобы файлы не перезаписывались, нужно условие if exist добавить

12

Re: Копирование файлов из одной папки в другую по дате

вывод dir %sourcedir%\ /O:D /A:-D
сюда, пожалуйста, предоставьте

вот

`dir %sourcedir%\*.txt /O:D /A:-D^`

13

Re: Копирование файлов из одной папки в другую по дате

смайл

14

Re: Копирование файлов из одной папки в другую по дате

гениально
я вообще-то результат команды просил
т.е. содержимое папки из которой копируете
:S
там файлы только с расширением txt?

15

Re: Копирование файлов из одной папки в другую по дате

Да, там только текстовые файлы

16

Re: Копирование файлов из одной папки в другую по дате

neperap, перечитайте пункт 4.4. Как правильно задать вопрос, чтобы быть услышанным «Правил…» и затем сделайте, что просят:

VitAliS пишет:

вывод

dir %sourcedir%\ /O:D /A:-D

сюда, пожалуйста, предоставьте

17

Re: Копирование файлов из одной папки в другую по дате

А что предоставить? Список файлов или скриншот?

18

Re: Копирование файлов из одной папки в другую по дате

Эти файлы были в исходной папке

brndlog.txt
dberr.txt
eula.txt
gmreadme.txt
h323log.txt
intro.txt
MachineGuid.txt
nav.txt
SchedLgU.Txt
segment1.txt
segment2.txt
segment3.txt
segment4.txt
segment5.txt

а такие папки появились в конечной папке

08.2001
10.2010
12.2001
12.2009
12.2010
в.устройстве
папок.10
файлов.69

то есть по датам файлы отсортировались, но вот эти три последние папки непонятно откуда берутся. И ещё в корне диска появляются пустые папки

320
549
550
704
706
752
968
984
991

выполняется такой код

@echo off
set sourcedir=c:\test
set destdir=c:\test22
for /F "usebackq tokens=(*),* delims=. " %%i in (`dir %sourcedir%\*.txt /O:D /A:-D^`) do (
if not exist %destdir%\%%j.%%k md %destdir%\%%j.%%k
copy /y %sourcedir%\%%n %destdir%\%%j.%%k\
)

19

Re: Копирование файлов из одной папки в другую по дате

ну раз там все файлы текстовые то тогда совсем просто

@echo off
set sourcedir=c:\test
set destdir=c:\test22
for /F "usebackq tokens=1-5,* delims=. " %%i in (`dir %sourcedir%\*.txt /O:D /A:-D^|findstr /R ".*\.txt$"`) do (
if not exist %destdir%\%%j.%%k md %destdir%\%%j.%%k
copy /y %sourcedir%\%%n %destdir%\%%j.%%k\
)

папки создаются потому что убрал findstr, он там стоит для того чтобы ненужные данные отбросить
сравните вывод команд

dir %sourcedir%\*.txt /O:D /A:-D

и

dir %sourcedir%\*.txt /O:D /A:-D|findstr /R ".*\.txt$"

и поймете для чего там findstr
и еще
"крышка" (^) не имеет отношения к команде dir, она используется для экранирования спецсимволов в данном случае "пайп" (|)

в общем открываем hh ntcmds.chm и просвещаемся

20

Re: Копирование файлов из одной папки в другую по дате

в общем открываем hh ntcmds.chm и просвещаемся

А где его взять? Простите с глупейшие вопросы, я как то больше по железякам привык работать:)

21

Re: Копирование файлов из одной папки в другую по дате

Спасибо за код, всё работает, как нужно!:)

22

Re: Копирование файлов из одной папки в другую по дате

neperap пишет:

А где его взять?

ввести в командной строке hh ntcmds.chm
это при условии что у Вас win XP

23

Re: Копирование файлов из одной папки в другую по дате

наздоровье

24

Re: Копирование файлов из одной папки в другую по дате

Сегодня первый раз запустил батник на клиентской машине, вываливается File not found. Возможна ли такая ошибка из-за установленной Windows 2000 на клиентской машине? Я где-то слышал, что у ХР командная строка отличается от 2k

25

Re: Копирование файлов из одной папки в другую по дате

neperap пишет:

Сегодня первый раз запустил батник на клиентской машине, …

Какой именно «батник»?

neperap пишет:

…вываливается File not found.

Приведите код скрипта. Приведите сообщение об ошибке, возможно, отключив «@echo off», чтобы увидеть, в какой строке она происходит.

26

Re: Копирование файлов из одной папки в другую по дате

alexii пишет:

Какой именно «батник»?

Батник с кодом, указанным чуть выше VitAliS

@echo off
set sourcedir=c:\test
set destdir=c:\test22
for /F "usebackq tokens=1-5,* delims=. " %%i in (`dir %sourcedir%\*.txt /O:D /A:-D^|findstr /R ".*\.txt$"`) do (
if not exist %destdir%\%%j.%%k md %destdir%\%%j.%%k
copy /y %sourcedir%\%%n %destdir%\%%j.%%k\
)

С отключённым "@echo off" так и происходит. Выполняется весь код до copy, и следом сообщение File not found. Т.е. как я понял, не получается создать папки на удалённой машине. Локально на моём компе всё работает, папки создаются и файлы копируются. По сети не хочет. Пути указаны правильно, на удалённый комп могу попасть в любую папку. Запускается под учётной записью админа. Связисты уже плешь проели своим нытьём

27

Re: Копирование файлов из одной папки в другую по дате

По приведённому коду:

set sourcedir=c:\test
set destdir=c:\test22

я не вижу упоминаний об удалённой машине. Приведите Ваш вариант скрипта, который не работает. Укажите как и откуда Вы его запускаете.

28

Re: Копирование файлов из одной папки в другую по дате

set sourcedir=\\pcitissvyaz9\d$\Log2
set destdir=L:\Backups\Ats37
for /F "usebackq tokens=1-5,* delims=. " %%i in (`dir %sourcedir%\*.txt /O:D /A:-D^|findstr /R ".*\.txt$"`) do (
if not exist %destdir%\%%j.%%k md %destdir%\%%j.%%k
copy /y %sourcedir%\%%n %destdir%\%%j.%%k\
)

Вот мой вариант кода. Запускается непосредственно на сервере. В исходную папку я попадаю без проблем, простая команда copy тоже выполняется

29

Re: Копирование файлов из одной папки в другую по дате

neperap пишет:

Запускается непосредственно на сервере.

Из какой папки запускается? Буквально хочу увидеть ответ, наподобие:

C:\Temp>0001.cmd

30

Re: Копирование файлов из одной папки в другую по дате

Запускается из папки L:\Backups\Ats37>ats37.bat,  в которую и должны складываться бэкапы

31 (изменено: neperap, 2011-01-13 09:29:49)

Re: Копирование файлов из одной папки в другую по дате

Разобрался в причине ошибки. В исходной папке файлы имеют расширение *.log, а не *.txt. Замена txt на log, и все дела

32

Re: Копирование файлов из одной папки в другую по дате

Понятно. Впрочем, всё равно не понятно. Ведь тогда, по идее, до

copy /y %sourcedir%\%%n %destdir%\%%j.%%k\

очередь и не дошла бы?

33

Re: Копирование файлов из одной папки в другую по дате

neperap пишет:

Выполняется весь код до copy, и следом сообщение File not found

copy и не выполнялась

34

Re: Копирование файлов из одной папки в другую по дате

если нужно чтобы файлы не перезаписывались, нужно условие if exist добавить

Не могу разобраться, куда это условие поставить...

35

Re: Копирование файлов из одной папки в другую по дате

Так вот я и не пойму, на что тогда было сие сообщение (от какой команды появлялось)?

и следом сообщение File not found

P.S. Это к посту #33

36

Re: Копирование файлов из одной папки в другую по дате

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

37

Re: Копирование файлов из одной папки в другую по дате

Судя по коду, попробуйте что-нибудь наподобие:

if not exist "%destdir%\%%j.%%k\%%n" copy "%sourcedir%\%%n" "%destdir%\%%j.%%k\"

38

Re: Копирование файлов из одной папки в другую по дате

Я сделал проще.

copy /-y %sourcedir%\%%n %destdir%\%%j.%%k\ <n.txt

В файле n.txt записана буква n. При запросе на перезапись получается отказ:)

39

Re: Копирование файлов из одной папки в другую по дате

А почему не?

echo n|copy…