【问题标题】:How can I use SSIS to conditionally rename each file in a directory with a unique name?如何使用 SSIS 有条件地使用唯一名称重命名目录中的每个文件?
【发布时间】:2019-01-02 20:57:16
【问题描述】:

我有一个包含 5 个包含日期时间信息的文件的目录。我需要从每个文件中删除日期时间并将每个文件重命名为友好名称。

我在想出这个任务的结构时遇到了麻烦,但我认为我需要在脚本任务中使用循环来有条件地重命名文件,但在互联网上没有找到很多执行此操作的示例功能。

我还考虑了一次重命名目录中所有文件的脚本任务。

任何指导都会很棒。

我尝试将 SSIS foreach 循环用于移动和重命名文件的文件任务,但它很笨重。 “一次且只有一次”在我脑海中响起,但我很难找到一种有效的方法来做到这一点。

在这篇文章中没有代码可以工作。

我想根据部分名称匹配重命名每个文件,以便目标目录包含排除不必要的日期信息的干净文件名。

假设文件命名如下: “EOY测试01012018.xls” “测试 PLA 01022018.xls” “测试 01032018 SHA.xls” “EAD 测试 01042018.xls” "测试 DOY 01052018.xls"

我想通过查找文件名称的一部分来有条件地重命名每个文件: 例子: 如果文件名像“EOY Test”那么“EOY_Test.XLS” 如果文件名像“Test PLA”那么“PLA_Test.XLS” 等等……

更新: 我不得不修改代码以从文件名中删除句点和其他一些字符。还添加了一个新变量和 directoryinfo 行来说明源文件夹和目标文件夹。这是来自@userfl89 答案的修改代码:

 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++;
            }

更新 2: 这是我得到的错误:

   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()

【问题讨论】:

  • 如果您有两个包含 EOY 或其他标识符的文件会怎样?您是只想在文件名末尾附加一个数字还是在文件名中使用日期时间?
  • 请假设除非日期更改,否则名称不会更改。我想完全消除名称中的日期部分并重命名文件。

标签: c# loops ssis


【解决方案1】:

以下是一个 C# 脚本任务,它将删除您列出的文件名的日期(数字)部分,并且不需要在任何类型的循环中执行。作为“保障”,每个文件都会附加一个代理编号,以使文件名唯一,以防一旦删除编号后它们还不是。如果您确定文件名在没有日期的情况下始终是唯一的,则可以删除添加到文件名中的 i int 变量。 Path.GetFileNameWithoutExtension 方法只获取文件名,避免创建名称中带有扩展名的文件,使文件无效。第一个Replace 方法用于删除数字,TrimEnd 方法省略了文本之间的尾随空格和之前的日期。然后将一个从 1 开始的递增数字添加到文件名中以确保唯一性。外部 Replace 方法用于将文件名中的单词之间的空格更改为下划线,如您的示例中所示,即测试 PLA 更改为 PLA_Test.XLS。将文件名更改为所需的输出后,使用MoveTo 方法移动(基本上覆盖)具有新名称的文件。如果文件夹路径存储在 SSIS 变量中,我对其进行了修改以从中获取文件夹,但如有必要,将其替换。如果使用变量来存储文件夹,请确保将此变量添加到脚本任务编辑器的ReadOnlyVariables 字段中。这将需要分别为文件和正则表达式操作引用 System.IOSystem.Text.RegularExpressions 命名空间。

        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++;
        }

【讨论】:

  • 抱歉耽搁了!我将尝试应用此功能,并会回复您。
  • 我尝试了该解决方案,但无法使其正常工作。我对其进行了一些修改,但是在执行时出现异常。我在上面添加了一些更多信息的更新。
  • 您遇到什么错误?如果多个文件在其名称被修改后具有相同的名称,则需要通过取消注释“i”int变量并将其添加到第二个替换方法位置后的文件名或通过另一个使这些名称唯一来使名称唯一方式。
  • 这是一个非常不友好的错误,没有足够的空间在评论中发布它。我会把它添加到主帖中。
  • 在带有 MessageBox.Show 的代码中使用 try...catch 块来打印错误消息或触发带有错误的事件,这将提供更精确的详细信息。
猜你喜欢
  • 2021-03-28
  • 1970-01-01
  • 2020-04-19
  • 2012-12-11
  • 2022-11-19
  • 2022-09-30
  • 2016-08-27
  • 1970-01-01
  • 2020-11-23
相关资源
最近更新 更多