1

What I have going on is this:
1) Reading a directory of files
2) Writing out to a text file the filenames + "|"
3) Where i'm stuck.....

I have a bunch of files named... and need to be converted corispondingly: Apple0154~3.Txt convertedTO -> Apple0156.txt
Apple0136~31.txt convertedTO -> Apple0166.txt

The prefix is always apple so it kinda goes like:
Apple (always the same prefix). The numbers match is # + ~ subnumber -1 always in in .txt

I'm sure this is confusing i'm using this code but i cant figured out how to get this resulting textfile:
Apple0154~3.Txt|Apple0156.txt
Apple0136~31.txt|Apple0166.txt

{
            string resultingfile = ***This is what i dont know***
            string movedredfolder = (overlordfolder + "\\redactions\\");
            DirectoryInfo movedredinfo = new DirectoryInfo(movedredfolder);
            using (StreamWriter output = new StreamWriter(Path.Combine(movedredfolder, "Master.txt")))
            {
                foreach (FileInfo fi in movedredfolder)
                {
                    output.WriteLine(Path.GetFileName(fi)+"|"+resultingfile);
                }
            }
        }
4
  • yes, this IS confusing. what logic is used to determine that "Apple0154~3" becomes "Apple0156"? Do I understand that you take the number after the ~ sign, subtract 1, and add that to the number before the ~ sign? Commented Jan 8, 2010 at 15:36
  • Static, I was failing the IQ test as well (-:. But the formula is in the question. Commented Jan 8, 2010 at 15:37
  • formulate is prefix <howevermany numbers> + <whatever after ~> -1 Commented Jan 8, 2010 at 15:40
  • 1
    lol! Seven code snippets submitted so far. Must be Friday! Commented Jan 8, 2010 at 15:50

5 Answers 5

3

Ok, I see what you are trying to do.

Try using Regular expressions to grab the 2 numbers out of the original file name. Something like:

Regex r = new Regex(@"Apple(\d+)~(\d+)\.txt");
Match mat = r.Match(filename);

if( !mat.Success )
{
    // Something bad happened...
    return;
}

int one = int.Parse(mat.Groups[1].Value);
int two = int.Parse(mat.Groups[2].Value);
int num = one + (two-1);

string newFilename = "Apple"+num.ToString("0000")+".txt";
Sign up to request clarification or add additional context in comments.

10 Comments

I agree. The first thing that came into my mind - Regex, no need to reinvent the wheel.
Shouldn't your regex be Apple(\d+)~(\d+)\.txt or am I a noob?
Even forgiving the missing backslash on the d+ and the non-escaped backslashes throughout, this regex does not work as you have the wrong groups. And, to be completely pedantic, there is no method named "parse" on the Int32 class.
@Jason: Fixed the Regex, and the lowercase p in Parse :-P but what do you mean about the wrong groups?
I'm going to look retarded if this is wrong, but I think if you compile and run the following string filename = "Apple0136~31.txt"; Regex r = new Regex(@"Apple(\d+)~(\d+)\.txt"); Match mat = r.Match(filename); Console.WriteLine(mat.Groups[0]); you'll see "Apple0136~31.txt" on the console. I just took the first two lines of your code and added a definition of filename and a Console.WriteLine statement.
|
1

Inside the foreach loop:

   string fileName = Path.GetFileName(fi);
   string[] parts = fileName.Split('~', '.');
   int basenum = int.Parse(parts[0].Substring(6));
   int offset = int.Parse(parts[1]);
   string resultingfile = string.Format("Apple{0:0000}.txt", basenum+offset-1);

Comments

0

euh something like:

 string path = Path.GetFileName(fi);
 int indexOfTilde = path.IndexOf('~');
 int indexOfPoint = path.LastIndexOf('.');
 int length = indexOfPoint -indexOfTilde; 
 string tmp = path.SubString(indexOfTilde+1, length);
 int numberToIncrease = Convert.ToInt32(tmp) - 1;
 int baseNumber = Convert.ToInt32(path.SubString(5, indexOfTilde-4);
 string newPath = "Apple" + (baseNumber + numberToIncrease ) + ".txt";

and you can use the FileInfo.MoveTo for file movement :) good luck!

edit: damn... too slow typing of me...

2 Comments

This is too brittle. It has too many magic constants and what not embedded in it.
sorry but i don't see why every answer needs a -1. ppl are trying to help out and everyone has it's own way and vision.
0

Ok, this should work for one file:

String filename = "Apple0154~3.Txt";
Regex re = new Regex(@"Apple(?<num>\d+)\~(?<add>\d+)");

Int32 num = Int32.Parse(re.Match(filename).Groups["num"].Value);
Int32 add = Int32.Parse(re.Match(filename).Groups["add"].Value);

Int32 rez = num + (add - 1);
MessageBox.Show("Apple" + rez + ".txt");

2 Comments

This answer would be better if it didn't assume that the prefix is always "Apple" and that the extension is always ".txt". No downvote, but no upvote either.
OK Jason, I am going to start an open source file renaming framework so we don't have all these "magic" constants!
-1
using (var output = new StreamWriter(Path.Combine(movedredfolder, "Master.txt")))
{
    foreach (var filePath in Directory.GetFiles(directoryPath))
    {
        var fileName = Path.GetFileNameWithoutExtension(filePath);
        var fileExtension = Path.GetExtension(filePath);
        var index = fileName.IndexOf('~'); 
        var firstNumber = Int32.Parse(fileName.Substring(5, index - 1)); 
        var secondNumber = Int32.Parse(fileName.Substring(index + 1)) - 1;
        output.Write("Apple0" + 
            (firstNumber + secondNumber).ToString() +
            fileExtension + "|"
        );
    }
}

4 Comments

He wants to know how to parse the numbers in the filename and combine using the formula he described
This is too brittle. It has too many magic constants and what not embedded in it.
Wow, so many sticklers today. Do you really think it makes a difference if I throw a couple const at the top? I didn't think so.
No, I think the preferred approach would be to avoid magic constants. Hence the regex answers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.