Member 12341536 Ответов: 2

Удаляйте последний файл каждого имени файла каждый месяц


Дорогие все,

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

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

Отчет 1 2017-08-01.xls
Отчет 1 2017-08-09.xls
Отчет 1 2017-08-27.xls
Отчет 1 2017-09-01.xls
Отчет 1 2017-09-09.xls
Отчет 1 2017-09-18.xls

Отчет 2 2017-08-01.xls
Отчет 2 2017-08-09.xls
Отчет 2 2017-08-27.xls
Отчет 2 2017-09-01.xls
Отчет 2 2017-09-09.xls
Отчет 2 2017-09-22.xls

Отчет 3 2017-08-01 blabla.xls
Отчет 3 2017-08-09 blabla.xls
Отчет 3 2017-08-27 blabla.xls
Отчет 3 2017-09-01 blabla.xls
Отчет 3 2017-09-09 blabla.xls
Отчет 3 2017-09-30 blabla.xls

Сейчас.

Я хочу удалить все файлы ожидайте последний файл каждого отчета каждого месяца.

Таков был бы результат. Удалить все файлы expext файлы:

Отчет 1 2017.08.27.xls
Отчет 1 2017-09-18.xls

Отчет 2 2017-08-27.xls
Отчет 2 2017-09-22.xls

Отчет 3 2017-08-27 blabla.xls
Отчет 3 2017-09-30 blabla.xls

Поэтому сначала я перечислил все файлы и соответствующую папку в Gridview.

Затем я извлек все даты с помощью регулярного выражения. Пока все хорошо.

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

Вот мой код.

      private void button1_Click(object sender, EventArgs e)
      {
          string fileName= "";



          string[] folders  = Directory.GetDirectories(@"C:\Test\", "*", System.IO.SearchOption.AllDirectories);



              for (int i = 0; i < folders.Length; i++)
              {
                  string temp = "";
                  Console.WriteLine("Pfad " + i + " " + folders.GetValue(i));
                  temp = folders.GetValue(i).ToString();

                  dataGridView1.Rows[i].Cells[0].Value = temp;


if ((Directory.GetFiles(temp, "*", SearchOption.TopDirectoryOnly).Length) == 0)

                  {

                 dataGridView1.Rows[i].Cells[1].Value = "No Files in Path";
                  }

                  else

                  {
                      for (int k = 0; k < (Directory.GetFiles(temp, "*", SearchOption.TopDirectoryOnly).Length); k++)
                      {
                          string tempfile = "";
                          tempfile = (Directory.GetFiles(temp, "*", SearchOption.TopDirectoryOnly).GetValue(k).ToString());
                      fileName = Path.GetFileName(tempfile).ToString();

                    Console.WriteLine(Regex.Match(fileName, @"\d{4}-\d{2}-\d{2}"));


                      dataGridView1.Rows[i + k].Cells[0].Value = temp;
                      dataGridView1.Rows[i + k].Cells[1].Value = Path.GetFileName(tempfile).ToString();
                      dataGridView1.Rows[i+k].Cells[2].Value = Regex.Match(fileName, @"\d{4}-\d{2}-\d{2}"));



                  }
                  }


              }
          }



Ваша помощь будет высоко оценена.

Большое спасибо.

Что я уже пробовал:

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

Graeme_Grant

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

Member 12341536

мне очень жаль, что я сделал это случайно

Graeme_Grant

Все благо. Наслаждайтесь решением... :)

2 Ответов

Рейтинг:
2

Ralf Meier

Как бы вы это сделали, если бы делали сами ?
Я бы построил список только с теми файлами, которые имеют одно и то же имя отчета, год и месяц.
Теперь отсортируйте этот список по убыванию - после этого вы получите самый последний файл сверху. Каждое имя файла в записи списка 1 или выше может быть удалено.
Повторите это со следующим месяцем, а затем со следующим годом, а затем со следующим именем отчета ...
Если ваши имена отчетов уникальны, вы можете сделать все это с помощью циклов ...


Рейтинг:
15

Graeme_Grant

Это сделает его лаконично для вас:

var inFiles = new List<string>
{
    "Report 1 2017-08-01.xls",
    "Report 1 2017-08-09.xls",
    "Report 1 2017-08-27.xls",
    "Report 1 2017-09-01.xls",
    "Report 1 2017-09-09.xls",
    "Report 1 2017-09-18.xls",
    "Report 2 2017-08-01.xls",
    "Report 2 2017-08-09.xls",
    "Report 2 2017-08-27.xls",
    "Report 2 2017-09-01.xls",
    "Report 2 2017-09-09.xls",
    "Report 2 2017-09-22.xls",
    "Report 3 2017-08-01 blabla.xls",
    "Report 3 2017-08-09 blabla.xls",
    "Report 3 2017-08-27 blabla.xls",
    "Report 3 2017-09-01 blabla.xls",
    "Report 3 2017-09-09 blabla.xls",
    "Report 3 2017-09-30 blabla.xls"
};

var deleteFiles = inFiles.Select(x => new { date = DateTime.Parse(Regex.Match(x, @"\d{4}-\d{2}-\d{2}").Value), file = x })
                            .Select(x => new { id = x.file.Replace(x.date.ToString("yyyy-MM-dd"), ""), date = x.date, file = x.file })
                            .OrderByDescending(x => x.date)
                            .GroupBy(x => x.id)
                            .SelectMany(x => x.Skip(1).Select(y => y.file));

foreach (var file in deleteFiles)
{
    Console.WriteLine(file);
}

Выходы:
Report 3 2017-09-09 blabla.xls
Report 3 2017-09-01 blabla.xls
Report 3 2017-08-27 blabla.xls
Report 3 2017-08-09 blabla.xls
Report 3 2017-08-01 blabla.xls
Report 2 2017-09-09.xls
Report 2 2017-09-01.xls
Report 2 2017-08-27.xls
Report 2 2017-08-09.xls
Report 2 2017-08-01.xls
Report 1 2017-09-09.xls
Report 1 2017-09-01.xls
Report 1 2017-08-27.xls
Report 1 2017-08-09.xls
Report 1 2017-08-01.xls


ОБНОВЛЕНИЕ
Чтобы сохранить самые последние данные каждого месяца, нам нужно расширить группировку, включив в нее также год и месяц. Это создаст больше групп, что мы и хотим:
var deleteFiles =
    inFiles.Select(x => new
                    {
                        date = DateTime.Parse(Regex.Match(x, @"\d{4}-\d{2}-\d{2}").Value),
                        file = x
                    })
            .Select(x => new
                    {
                        id = x.file.Replace(x.date.ToString("yyyy-MM-dd"), ""),
                        year = x.date.Year,
                        month = x.date.Month,
                        date = x.date,
                        file = x.file
                    })
            .OrderByDescending(x => x.date)
            .GroupBy(x => new { id = x.id, year = x.year, month = x.month })
            .SelectMany(x => x.Skip(1).Select(y => y.file));

Теперь выход есть:
Report 3 2017-09-09 blabla.xls
Report 3 2017-09-01 blabla.xls
Report 2 2017-09-09.xls
Report 2 2017-09-01.xls
Report 1 2017-09-09.xls
Report 1 2017-09-01.xls
Report 1 2017-08-09.xls
Report 1 2017-08-01.xls
Report 2 2017-08-09.xls
Report 2 2017-08-01.xls
Report 3 2017-08-09 blabla.xls
Report 3 2017-08-01 blabla.xls

Вот бонусный фрагмент кода для вас... Он сообщит вам, какие файлы хранятся:
Console.WriteLine("-- Keeping:");
foreach (var file in inFiles.Except(deleteFiles))
{
    Console.WriteLine(file);
}

Который выводит:
-- Keeping:
Report 1 2017-08-27.xls
Report 1 2017-09-18.xls
Report 2 2017-08-27.xls
Report 2 2017-09-22.xls
Report 3 2017-08-27 blabla.xls
Report 3 2017-09-30 blabla.xls


Member 12341536

Привет greame_Grant большое вам спасибо за ваш ответ.
Я не уверен, что это все, что мне нужно. Ваш вывод дает мне файлы, которые должны быть удалены правильно? Но они содержат файлы, которые тоже не должны быть удалены. Он оставляет мне только последние файлы за последний месяц. Но, как уже упоминалось, он мне нужен на каждый месяц.

файл

Отчет 1 2017-08-27.xls
Отчет 2 2017-08-27.xls
Отчет 3 2017-08-27 blabla.xls

не следует также удалять.

Очень ценю вашу помощь.

Graeme_Grant

Фреймворк есть, вам просто нужно изменить группировку на id, затем год, затем месяц.

Решение обновлено... ;)

Member 12341536

Большое спасибо, очень ценю вашу помощь. Спасибо

Graeme_Grant

Мы всегда рады вам. Я надеюсь, что с тем, как этот код изложен, легко увидеть, что он делает... ;)

Ralf Meier

+5

Member 12341536

Привет, грим, у меня есть проблема, и я надеялся, что ты сможешь мне помочь.

Сначала все было хорошо но это бросает мне эту ошибку (
Система.Formatexception версия: "строка не распознана как действительное значение datetime.")
Имя файла - "60-40-Ratio-Report - xxx@blbla.de 2017-08-08.xlsx"


И знаете почему? Большое спасибо

Graeme_Grant

Я проверил его здесь и отлично работает. Вот дамп из окна немедленной отладки:

DateTime.Parse(Regex.Match("60-40-Ratio-Report - xxx@blbla.de 2017-08-08.xlsx", @"\d{4}-\d{2}-\d{2}").Value)
{8/08/2017 12:00:00 AM}
    Date: {8/08/2017 12:00:00 AM}
    Day: 8
    DayOfWeek: Tuesday
    DayOfYear: 220
    Hour: 0
    Kind: Unspecified
    Millisecond: 0
    Minute: 0
    Month: 8
    Second: 0
    Ticks: 636377472000000000
    TimeOfDay: {00:00:00}
    Year: 2017

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

Member 12341536

Спасибо, грим.. Большое спасибо.