How to get files from 1 to n in a particular pattern?
Suppose you have files like:
NewFile.part01.zip
NewFile.part02.zip
NewFile.part04.zip
NewFile.part06.zip
NewFile.part07.zip
How do you get the files in this patter so you only get a SINGLE file called "NewFile" and also get the missing ones as integers, in this case (3, 5)
开发者_StackOverflow中文版Right now I am checking files one by one and if the name only differs in the suffix then skipping, also checking the number is +1 than the previous, etc.
But I thought someone might have a better, more elegant way of doing this. Linq, regex, etc?
EDIT:
So the way to know when the continuous files end is when the last file size has a difference than others. So it's like 200mb, 200mb, 200mb, ..., then the last one is 196mb.
My input is the full file list with the path like:
"C:\NewFile.part01.zip"
"C:\NewFile.part02.zip"
...
You can use regex that looks like this
^(?<name>.*)\.part(?<num>\d{0,})\.zip$
which should give you two group matches, one for the filename and one for the num
Do a loop, collect the info and then you can identify the name and numbers (store in a list). If you like you can use linq in loop like this to identify the missing number set
foreach(int i = list.Min(); i <= list.Max(); i++)
{
if (!list.Contains(i))
missingNums.Add(i);
}
--- Edited to give example as requested
This is the example how you will use the regex to iterate through your file list
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);
}
}
Okay, first of all, you can extract a number from filename:
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);
}
Now, you can check the missing numbers.
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);
If you know the file names try something like this (LINQ's "Except"):
string[] seq1 = { "NewFile.part01.zip", "NewFile.part03.zip"};
string[] seq2 = { "NewFile.part01.zip", "NewFile.part02.zip", "NewFile.part03.zip" };
var diffs = seq2.Except(seq1);
PK :-)
(I just saw your edit but now not so clear on the question)
In dos, simply type:
copy "c:\NewFile.Part??.zip" "c:\NewFile.zip" /b
Don't forget the /b or it will process command codes differently and turn any '0x0d' or '0x0a' characters into the char pair '0x0d0a'
精彩评论