简体   繁体   中英

How can I use SSIS to conditionally rename each file in a directory with a unique name?

I have a directory with 5 files containing datetime information. I need to strip the datetime from each file and rename each file to a friendly name.

I'm having trouble coming up with the structure of this task, but I think I need to use a loop that in a script task to rename the file conditionally, but haven't found many examples on the internet that perform this function.

I also considered a script task that renames all of the files in the directory at once.

Any guidance would be great.

I've tried to use SSIS foreach loop with file tasks that move and rename files, but it's clunky. "Once and only once" rings in my head, but I'm having trouble working out an efficient method of doing this.

There is no code that works as of this post.

I would like to rename each file based on a partial name match so that the destination directory contains clean filenames that exclude unnecessary date information.

Let's say that the files are named as follows: "EOY Test 01012018.xls" "Test PLA 01022018.xls" "Test 01032018 SHA.xls" "EAD Test 01042018.xls" "Test DOY 01052018.xls"

I want to rename each file conditionally by finding part of their name: Examples: If fileName like "EOY Test" then "EOY_Test.XLS" If fileName like "Test PLA" then "PLA_Test.XLS" etc...

UPDATE: I had to modify the code to also remove periods and a few other characters from the filename. Also added a new variable and directoryinfo line to account for source and destination folders. Here's the modified code from @userfl89 's answer:

 string fileDirectory_Source = Dts.Variables["User::PayrollSourceFilePath"].Value.ToString();
            string fileDirectory_Dest = Dts.Variables["User::PayrollDestFilePath"].Value.ToString();
            DirectoryInfo dirInfo_Source = new DirectoryInfo(fileDirectory_Source);
            DirectoryInfo dirInfo_Dest = new DirectoryInfo(fileDirectory_Dest);
            ///
            ///int i = 1;

            foreach (FileInfo fi in dirInfo_Source.EnumerateFiles())
            {
                ///Replace(" ", "_") + i 
                string newFileName = Regex.Replace(Path.GetFileNameWithoutExtension(fi.Name), "[0-9]|[.,/ -]", "").TrimEnd()+ fi.Extension;
                fi.MoveTo(dirInfo_Dest + newFileName);
                ///i++;
            }

UPDATE 2: This is the error I'm getting:

   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
   at Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTATaskScriptingEngine.ExecuteScript()

The following is a C# Script Task that will remove the date (numeric) part of the file names as you listed and does not need to be executed within any type of loop. As a "safeguard" a surrogate number is appended to each file in order to make the files names unique in case they weren't already once the numbers are removed. If you're sure that the file names will always be unique without the dates you can just remove the i int variable that's added to the file name. The Path.GetFileNameWithoutExtension method gets only the file name to avoid creating the file with the extension in the name and making the file invalid. The first Replace method is used to remove the numbers, with the TrimEnd method omitting the trailing space between the text and where the dates were before this. An incrementing number that starts at 1 is then added to the file name to ensure uniqueness. The outer Replace method is used to change the space between the words in the files names to underscores as in your example, ie Test PLA changes to PLA_Test.XLS. After changing the file name to the desired output, the MoveTo method is used move, basically overwrite, the files with their new names. In case the folder path is stored in an SSIS variable I modified this to obtain the folder from such, however this be replaced if necessary. If a variable is used to store the folder make sure to add this variable in the ReadOnlyVariables field on the Script Task Editor. This will require references to the System.IO and System.Text.RegularExpressions namespaces for the file and Regex operations, respectively.

        string fileDirectory = Dts.Variables["User::FolderPath"].Value.ToString();
        DirectoryInfo dirInfo = new DirectoryInfo(fileDirectory);

        int i = 1;

        foreach (FileInfo fi in dirInfo.EnumerateFiles())
        {
            string newFileName = Regex.Replace(Path.GetFileNameWithoutExtension(fi.Name), "[0-9]", "").TrimEnd().Replace(" ", "_") + i + fi.Extension;
            fi.MoveTo(fileDirectory + newFileName);
            i++;
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM