尝试使用Windows命令行命令编写C#等效批处理文件

时间:2016-06-10 09:04:44

标签: c# batch-file

我不知道批处理文件和Windows命令行,我正在尝试编写一个批处理文件,该文件将在给定的文件夹位置运行并验证其中存在的所有文件的文件名。

可以使用正则表达式验证文件名:

^[a-zA-Z0-9]{1,20}\-[a-zA-Z0-9]{1,40}\-[0-9]{8}(\-[0-9]+)?\.[a-zA-Z]{2,4}$

鉴于正则表达式是正确的。

或者,如果正则表达式没用,则在人类语言中,文件名应为:

  

alphaNumerricMax20char-alphaNumerricMax40char-8charDateofFormatyyyyMMdd.extension

我之前写了一个C#代码,如下所示:

        rtbResult.Text = string.Empty;
        List<string> fileNamesNotValid = new List<string>();
        string[] allFilesInDirectory = new string[0];
        try
        {
            if (Directory.Exists(txtFolderLocation.Text))
            {
                allFilesInDirectory = Directory.GetFiles(txtFolderLocation.Text);
                foreach (string file in allFilesInDirectory)
                {
                    var fileName = Path.GetFileName(file);

                    if (Regex.IsMatch(fileName, @"^[a-zA-Z0-9]{1,20}\-[a-zA-Z0-9]{1,40}\-[0-9]{8}(\-[0-9]+)?\.[a-zA-Z]{2,4}$"))
                    {
                        var dataComponent = fileName.Split('-')[2].Split('.')[0];
                        try
                        {
                            DateTime date = DateTime.ParseExact(dataComponent, "yyyyMMdd",
                                                      System.Globalization.CultureInfo.InvariantCulture);
                            if (date > DateTime.Now)
                            {
                                fileNamesNotValid.Add(fileName);
                            }
                        }
                        catch (Exception)
                        {
                            fileNamesNotValid.Add(fileName);
                        }

                    }
                    else
                    {
                        fileNamesNotValid.Add(fileName);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        foreach (var item in fileNamesNotValid)
        {
            rtbResult.Text += item + "\n";
        }

        MessageBox.Show("Process Completed!!\n Total Files proccessed = " + allFilesInDirectory.Count() + "\n Total Invalid Files = " + fileNamesNotValid.Count);

1 个答案:

答案 0 :(得分:0)

这是一个非常挑战的问题,而且我并不完全确定它确实与OP要求的完全相同,但我忍不住尝试提出某种解决方案。由于无法使用实际正则表达式完全测试文件名,因此您必须有点创意。

批处理首先创建所有文件名列表。然后迭代遍历所有这些文件名,使用破折号和句点将每个文件名分成4个组件:

  • AlphaNumeric(最多20个字符)
  • AlphaNumeric(最多40个字符)
  • 日期(8位数)
  • 扩展名(至少2个字母字符)

如果名称中包含4个以上的组件,则会引发错误。这会自动处理文件名中的空格。

首先检查每个组件的最大允许长度。如果它通过了那个检查,那么它将被送到FINDSTR来检查所提供的字符列表中的任何字符(这是字符类的FindStr限制真正明显的地方,因为你不能否定一个完整的字符集,如[^ 0-9],例如,但是很好......)。如果在组件中找到任何不需要的字符,则会引发错误。

所有通过所有检查的文件名都将写入Success.txt文件。所有有错误的人都会被写入Error.txt文件。

@Echo off
setlocal EnableDelayedExpansion
if exist error.txt del error.txt
if exist success.txt del success.txt
dir /b *.c* > tmp.tmp
set success=false
for /f %%i in (tmp.tmp) do (
  for /f "tokens=1,2,3,4* delims=-." %%a in ("%%i") do (
    REM 5 chunks means there's an error
    REM Spaces in filename will automatically cause an error (which is OK)
    if "%%e"=="" (
      REM less than 4 chunks means there's an error
      if "%%d"=="" (
        call :errProcess %%i "ERROR, missing chunks"
      ) else (
        REM At this stage we need to validate if:
        REM %%a contains [a-Z0-9]{1,20}
        REM %%b contains [a-Z0-9]{1,40}
        REM %%c contains [0-9]{8}
        REM %%d contains [a-Z]{2}
        set tmp=%%a
        if "!tmp:~20,1!" == "" (
          call :checkRegEx %%i %%a abcdefghijklmnopqrstuvwxyz0123456789
          if !success!==true (
            set tmp=%%b
            if "!tmp:~40,1!" == "" (
              call :checkRegEx %%i %%b abcdefghijklmnopqrstuvwxyz0123456789
              if !success!==true (
                set tmp=%%c
                if "!tmp:~8,1!" == "" (
                  call :checkRegEx %%i %%c 0123456789
                  if !success!==true (
                    set tmp=%%d
                    if "!tmp:~1,1!" == "" (
                      REM Extension must be at least 2 characters long
                      call :errProcess %%i "ERROR, ^"!tmp!^" is LSS than 2"
                    ) else (
                      call :checkRegEx %%i %%d abcdefghijklmnopqrstuvwxyz
                      if !success!==true (
                        call :success %%i
                      )
                    )
                  )
                ) else (
                  call :errProcess %%i "ERROR, ^"!tmp!^" is GTR than 8"
                )
              )
            ) else (
              call :errProcess %%i "ERROR, ^"!tmp!^" is GTR than 40"
            )
          )
        ) else (
          call :errProcess %%i "ERROR, ^"!tmp!^" is GTR than 20"
        )
      )
    ) else (
      call :errProcess %%i "ERROR, too many chunks"
    )
  )
  rem FindStr /R "[a]" %%i 

)
del tmp.tmp
goto :eof

:errProcess
set strTmp=%2
Echo %1 : %strTmp:~1,-1%
Echo %1 >> Error.txt
goto :eof

:success
Echo %1 : SUCCESS
Echo %1 >> Success.txt
goto :eof

:checkRegEx
REM checkregEx filename "string" [regEx] (always a negated RegEx)
set zeFile=%1
set zeString=%2
set zeRegEx=%3
set success=false
set unwantedChar=
FOR /F "tokens=*" %%i IN ('echo %zeString%^| findstr /i "[^%zeRegEx%]"') DO (
  SET unwantedChar=%%i
  call :errProcess %zeFile% "ERROR, %zeString% does not match RegEx"
)
if "!unwantedChar!"=="" (
  set success=true
)
set zeString=
set zeRegEx=
goto :eof