计算字符串(批处理文件)中字符的出现次数



我需要在windows中创建一个批处理文件来解析文件夹中所有可用的文件名,并将符合某些条件的文件移动到文件夹中。我已经用FOR命令创建了循环,并将文件名设置为一个变量。现在我需要检查文件名的变量中有多少"-"hypen字符;如果该字符的出现次数超过10次,则不应移动该文件。此外,我还需要检查文件名中是否有空格:在这种情况下,文件也不能移动。请:我可以用什么方式创建脚本来检查变量中hypen的出现次数和空格字符的存在?

非常感谢

此代码仅使用for /f标记器来确定是否应复制或排除文件。在炒作的情况下,10个-字符生成11个令牌,或多或少是排除的原因。在空间的情况下,单个空间生成两个令牌。这是简单的部分,但是

  • 由于可能存在hypen的运行,并且for /f标记化器仅将连续的分隔符作为一个分隔符来处理,因此每个hypen都替换为-#和前缀为#的文件名,以确保正确的拆分。

  • 要进行字符串替换,我们需要一个普通变量,而不是for可替换参数。因此,我们需要延迟扩展才能读取更改后的变量的内容。但是,由于延迟扩展处于活动状态,!字符将成为一个问题,因为解析器将尝试将其解释为变量引用。为了避免这种情况,延迟扩展仅在需要时启用,并再次禁用。

  • 为了处理空间分割,文件名的前缀和后缀都是#,以确保正确处理起始或结束空间。

@echo off
    setlocal enableextensions disabledelayedexpansion
    rem Generate a set of test files
    type nul > "0-1-2-3-4-5-6-7-8-9-10-11-12.testFile"
    type nul > "0-1-2-3-4-5-6-7-8-9-10-11.testFile"
    type nul > "0-1-2-3-4-5-6-7-8-9-10.testFile"
    type nul > "0-1-2-3-4-5-6 -7-8-9-10.testFile"
    type nul > "0-1-2-3-4-5-6-7-8-9.testFile"
    type nul > "-----------.testFile"
    type nul > "----------.testFile"
    type nul > "!-----------!.testFile"
    type nul > "!----------!.testFile"
    type nul > "noSpaces.testFile"
    type nul > "this file has spaces.testFile"
    type nul > "0-1-2-3-4-5!!-6-!!7-8-9-10-11-12.testFile"
    type nul > "0-1-2-3-4-5!!-6-!!7-8-9-10-11.testFile"
    type nul > "0-1-2-3!!-4-5-6-7-8-9!!-10.testFile"
    type nul > "0-1-2-3!!-4-5-6-7-8!-!9.testFile"
    type nul > "no!Sp!aces.testFile"
    type nul > "this !file! has spaces.testFile"

    for %%f in (*) do (
        rem The default behaviour is not to exclude the file
        set "exclude="
        rem Test the hypen conditions
        set "fileName=%%~nf"
        setlocal enabledelayedexpansion
        for /f "tokens=1,11,12 delims=-" %%a in ("#!fileName:-=-#!") do (
            endlocal 
            rem Testing less than 10 hypen
            if "%%~b"=="" set "exclude=1"
            rem Testing more than 10 hypen
            if not "%%~c"=="" set "exclude=1"
        )
        rem Test if the file name contains a space
        for /f "tokens=1,2" %%a in ("#%%~nf#") do if not "%%~b"=="" set "exclude=1" 
        rem Now we know what to do with the file
        if defined exclude (
            echo EXCLUDE "%%~ff"
        ) else (
            echo COPY "%%~ff"
        )
    )
    del /q "*.testFile"

另一种方法是过滤文件列表,只检索那些应该被处理的文件

for /f "delims=" %%a in ('
    dir /b 
    ^| findstr /v /c:" " 
    ^| findstr /r /x /c:"[^-]*-[^-]*-[^-]*-[^-]*-[^-]*-[^-]*-[^-]*-[^-]*-[^-]*-[^-]*-[^-]*"
') do echo COPY %%~fa

确定字符串中包含的连字符数的一个简单方法是将原始字符串的长度与去掉连字符的字符串的长度进行比较:连字符数是长度的差。

1. Save the length of the original string
2. Remove all hyphens from the string
3. Compare the length of the new string to that of the original:
        originalLength - newLength = numberOfHyphens

类似地,此方法可用于确定是否存在空间。如果原始字符串的长度大于字符串的长度减去空格,则空格必须已被删除,因此必须存在于原始字符串中。

如果我正确理解了你的意思,你其实并不想知道一个名字有多少个hypens,只是想知道这个名字是否有超过10个hypens。这可以通过for /F命令的"tokens=12 delims=-"选项轻松实现:

编辑:根据注释中的新请求修改代码。新代码检查名称是否正好包含10个hypens并且不包含空格。

@echo off
setlocal
for %%a in (one-two-three-four-five-six-seven-eight-nine-end.txt
            one-two-three-four-five-six-seven-eight-nine-ten-end.txt
            one-two-three-four-five-six--eight-nine-ten-end.txt
            one-two-three-four-five---eight-nine-ten-end.txt
            one-two-three-four-five----nine-ten-end.txt
            one-two-three-four-five-----ten-end.txt
            one----------end.txt
            ----------.txt
            one-two-three-four-five-six-seven-eight-nine-ten-eleven-end.txt
            "one-two-three-four-five-SIX SEVEN--eight-nine-ten-end.txt") do (
   set "fileName=%%~a"
   call :checkName
)
goto :EOF

:checkName
echo Checking "%fileName%"
set "result=Don't have 10 hypens"
for /F "tokens=11,12 delims=-" %%a in ("%filename:--=X-X-X%") do (
   if "%%a" neq "" if "%%b" equ "" set "result=Name correct"
)
for /F "tokens=2" %%a in ("%fileName%") do if "%%a" neq "" set "result=Include space"
echo %result%
exit /B

最新更新