Как получить файлы от 1 до n по определенному шаблону? - PullRequest
0 голосов
/ 22 февраля 2010

Предположим, у вас есть файлы вроде:

NewFile.part01.zip
NewFile.part02.zip
NewFile.part04.zip
NewFile.part06.zip
NewFile.part07.zip

Как вы получаете файлы в этом шаблоне, чтобы вы получили только ОДИН файл с именем «NewFile», а также получили недостающие в виде целых чисел, в данном случае (3, 5)

Сейчас я проверяю файлы один за другим, и если имя отличается только суффиксом, то пропускаю, также проверяю номер на +1, чем предыдущий, и т. Д.

Но я подумал, что у кого-то может быть лучший, более элегантный способ сделать это. Linq, регулярные выражения и т.д?

EDIT:

Таким образом, способ узнать, когда непрерывные файлы заканчиваются, - это когда размер последнего файла отличается от других. Таким образом, это как 200 МБ, 200 МБ, 200 МБ, ..., а затем последний 196 МБ.

Мой ввод - это полный список файлов с путем:

"C:\NewFile.part01.zip"
"C:\NewFile.part02.zip"
...

Ответы [ 4 ]

2 голосов
/ 22 февраля 2010

Вы можете использовать регулярное выражение, похожее на это

^(?<name>.*)\.part(?<num>\d{0,})\.zip$

, который должен дать вам два совпадения группы, один для имени файла и один для числа

Сделайте цикл, соберите информацию, а затем вы можете определить имя и номера (сохранить в списке). Если вам нравится, вы можете использовать linq в цикле, как это, чтобы определить пропущенный набор номера

foreach(int i = list.Min(); i <= list.Max(); i++)
{
  if (!list.Contains(i))
    missingNums.Add(i);
}

--- Отредактировано, чтобы привести пример в соответствии с просьбой

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

   string pattern = @"^(?<name>.*)\.part(?<num>\d{0,})\.zip$";
    foreach(string file in files)
    {
        Match match = Regex.Match(file, pattern);
        if (match.Success && match.Groups.Count >= 2)
        {
            string filename = match.Groups["name"].Value;
            int num = Convert.ToInt32(match.Groups["num"].Value);
        }
    }
2 голосов
/ 22 февраля 2010

Хорошо, во-первых, вы можете извлечь число из имени файла:

int ExtractNumber(string filename)
{
    filename = filename.Remove(filename.LastIndexOf('.'));
    filename = filename.Remove(0, filename.LastIndexOf('.') + 1);
    filename = filename.Remove(0, 4); // "part"
    return int.Parse(filename);
}

Теперь вы можете проверить пропущенные номера.

HashSet<int> existingNumbers = new HashSet<int>();
int max = -1;
foreach (string fn in filenameList)
{
    int n = ExtractNumber(fn);
    existingNumbers.Add(n);
    max = Math.Max(max, n);
}
HashSet<int> nonExistingNumbers = new HashSet<int>();
for (int i = 0; i <= n; i++)
    if (!existingNumbers.Contains(i))
        nonExistingNumbers.Add(i);
1 голос
/ 22 февраля 2010

Если вы знаете имена файлов, попробуйте что-то вроде этого (LINQ "За исключением"):

string[] seq1 = { "NewFile.part01.zip", "NewFile.part03.zip"};
string[] seq2 = { "NewFile.part01.zip", "NewFile.part02.zip", "NewFile.part03.zip" };
var diffs = seq2.Except(seq1);

ПК: -)

(я только что видел ваше изменение, но теперь не очень ясно по вопросу)

0 голосов
/ 22 февраля 2010

В дос, просто введите:

copy "c:\NewFile.Part??.zip" "c:\NewFile.zip" /b

Не забудьте о / b, иначе он будет обрабатывать коды команд по-разному и превратить любые символы «0x0d» или «0x0a» в пару символов «0x0d0a»

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