批量文件中找出每个文件名相同且序号最大的文件

迷之程序员 2018-04-10 03:30:40
是这样的,有几个文件夹,每一个之中有这样一大批压缩文件,
每个文件都遵循一样的命名规则:name_123.zip
现在要做的就是选中一个文件夹,选出相同name文件中序号最大的文件。
其实就是选出这些文件中每一个的最新版本,做一个全部文件最新版本的集合。
然后删除其余的文件。
关键就是需要对文件名进行操作,选出么一个相同名字中排序号最大的


我的想法是用C+、批处理或是MFC都可以,但具体怎么实现还不知道
现在只是用批处理提取了全部文件的文件名
2018/04/09 09:38 57,647 TapCffexQtGw_SP13_121.zip
2018/04/09 09:38 57,374 TapCffexQtGw_SP13_293.zip
2018/04/09 09:38 57,481 TapCffexQtGw_SP13_485.zip
2018/04/09 09:38 57,522 TapCffexQtGw_SP13_500.zip
2018/04/09 09:38 56,064 TapCffexQtGw_SP13_618.zip
2018/04/09 09:38 185,584 TapDceQtGw_SP13_122.zip
2018/04/09 09:38 185,674 TapDceQtGw_SP13_288.zip
2018/04/09 09:38 185,727 TapDceQtGw_SP13_361.zip
2018/04/09 09:38 185,743 TapDceQtGw_SP13_492.zip
2018/04/09 09:38 185,415 TapDceQtGw_SP13_620.zip
2018/04/09 09:38 55,612 TapIneQtGw_SP13_416.zip
2018/04/09 09:38 55,431 TapIneQtGw_SP13_501.zip
2018/04/09 09:38 54,480 TapIneQtGw_SP13_631.zip
2018/04/09 09:38 54,507 TapIneQtGw_SP13_636.zip
2018/04/09 09:38 84,456 TapMiniQtFront_SP13_248.zip
2018/04/09 09:38 84,937 TapMiniQtFront_SP13_401.zip
2018/04/09 09:38 84,916 TapMiniQtFront_SP13_624.zip
2018/04/09 09:38 84,699 TapMiniQtFront_SP13_729.zip
2018/04/09 09:38 84,415 TapMiniQtFront_SP13_76.zip
2018/04/09 09:38 4,464,424 TapQuoteApi_55.zip
2018/04/09 09:38 4,471,159 TapQuoteApi_56.zip
2018/04/09 09:38 57,855 TapShfeQtGw_SP13_123.zip
2018/04/09 09:38 57,903 TapShfeQtGw_SP13_290.zip
2018/04/09 09:38 57,905 TapShfeQtGw_SP13_294.zip
2018/04/09 09:38 57,993 TapShfeQtGw_SP13_484.zip
2018/04/09 09:38 58,030 TapShfeQtGw_SP13_502.zip
2018/04/09 09:38 56,817 TapShfeQtGw_SP13_619.zip
...全文
1283 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
迷之程序员 2018-04-16
  • 打赏
  • 举报
回复
进展:已经完成啦,通过一天的不懈努力,最终完成了。毕竟是在C#winform 开发的一个工具,所以基本上还是靠自己慢慢写出来的。将文件名提取之后分解成名字和序号,对名字循环,当找到不同名的时候对这一组的序号提取最大值,然后拼接名字和序号完成下载。具体的我发了个文章记录了下来 https://blog.csdn.net/baidu_39486224/article/details/79961024总之谢谢大家
迷之程序员 2018-04-14
  • 打赏
  • 举报
回复
进展:前两天在忙别的事情,现在这个功能要在C# winform里面做了。今天我又做了一些工作:我将所有文件名给了一个string[] AllFiles,然后 现在需要对这个数组进行组合,找出每一种的版本号最大的提取出来。大家写的思路我也在看,我也在思考,有新的建议也请提出来
赵4老师 2018-04-11
  • 打赏
  • 举报
回复
system("dir /b /a-d c:\\*.* >d:\\allfiles.txt"); //读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字 system("dir /b /a-d /s c:\\*.* >d:\\allfilesinsub.txt"); //读文件d:\\allfilesinsub.txt的内容即C:\\下所有文件的名字包含子目录 system("dir /b /ad c:\\*.* >d:\\alldirs.txt"); //读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字 请记住,能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作,而不要用各种API获取或者操作,因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时,API会处理的不全面或陷入死循环,而shell命令不会。 如果嫌system黑窗口一闪,将system("...")替换为WinExec("cmd /c ...",SW_HIDE); 使用以上思路,将处理文件列表的问题转换为处理文本文件问题。
yiyefangzhou24 2018-04-11
  • 打赏
  • 举报
回复
批处理就能实现了,整个程序,忽略开发周期??
  • 打赏
  • 举报
回复
用 Wps表格或者Excel 做, 1、dir /b > a.csv 2、WPS打开a.csv,分列,用下划线分。 3、对感兴趣列排序 4、拖出脚本 del 文件名 5、新建一个 b.bat文件,复制拖出的脚本 6、运行,OK 可以看看这篇文章 https://blog.csdn.net/goldenhawking/article/details/73095549
  • 打赏
  • 举报
回复
引用 13 楼 baidu_39486224 的回复:
[quote=引用 11 楼 DelphiGuy 的回复:] 批处理就几行的事情还写程序 保存以下文本到一个.bat(name改成你需要的文件名,或者作为命令行参数%1、%2之类的输入): @echo off set MAX_NUM=0 for /f "tokens=2 delims=_." %%i in ('dir /b /-p name_*.zip') do if /I "%MAX_NUM%" lss "%%i" set /a MAX_NUM=%%i 2>nul echo name_%MAX_NUM%.zip set MAX_NUM=
我需要自动提取每种文件名称啊..[/quote] 那只需要把'dir /b /-p name_*.zip'这里的name_*.zip换成%1,然后在命令参数里输入文件名(假设批处理文件名为test):test xxxx_*.zip
赵4老师 2018-04-11
  • 打赏
  • 举报
回复
C:\>set /? 显示、设置或删除 cmd.exe 环境变量。 SET [variable=[string]] variable 指定环境变量名。 string 指定要指派给变量的一系列字符串。 要显示当前环境变量,键入不带参数的 SET。 如果命令扩展被启用,SET 会如下改变: 可仅用一个变量激活 SET 命令,等号或值不显示所有前缀匹配 SET 命令已使用的名称的所有变量的值。例如: SET P 会显示所有以字母 P 打头的变量 如果在当前环境中找不到该变量名称,SET 命令将把 ERRORLEVEL 设置成 1。 SET 命令不允许变量名含有等号。 在 SET 命令中添加了两个新命令行开关: SET /A expression SET /P variable=[promptString] /A 命令行开关指定等号右边的字符串为被评估的数字表达式。该表达式 评估器很简单并以递减的优先权顺序支持下列操作: () - 分组 ! ~ - - 一元运算符 * / % - 算数运算符 + - - 算数运算符 << >> - 逻辑移位 & - 按位“与” ^ - 按位“异” | - 按位“或” = *= /= %= += -= - 赋值 &= ^= |= <<= >>= , - 表达式分隔符 如果您使用任何逻辑或取余操作符, 您需要将表达式字符串用 引号扩起来。在表达式中的任何非数字字符串键作为环境变量 名称,这些环境变量名称的值已在使用前转换成数字。如果指定 了一个环境变量名称,但未在当前环境中定义,那么值将被定为 零。这使您可以使用环境变量值做计算而不用键入那些 % 符号 来得到它们的值。如果 SET /A 在命令脚本外的命令行执行的, 那么它显示该表达式的最后值。该分配的操作符在分配的操作符 左边需要一个环境变量名称。除十六进制有 0x 前缀,八进制 有 0 前缀的,数字值为十进位数字。因此,0x12 与 18 和 022 相同。请注意八进制公式可能很容易搞混: 08 和 09 是无效的数字, 因为 8 和 9 不是有效的八进制位数。 /P 命令行开关允许将变量数值设成用户输入的一行输入。读取输入 行之前,显示指定的 promptString。promptString 可以是空的。 环境变量替换已如下增强: %PATH:str1=str2% 会扩展 PATH 环境变量,用 "str2" 代替扩展结果中的每个 "str1"。 要有效地从扩展结果中删除所有的 "str1","str2" 可以是空的。 "str1" 可以以星号打头;在这种情况下,"str1" 会从扩展结果的 开始到 str1 剩余部分第一次出现的地方,都一直保持相配。 也可以为扩展名指定子字符串。 %PATH:~10,5% 会扩展 PATH 环境变量,然后只使用在扩展结果中从第 11 个(偏 移量 10)字符开始的五个字符。如果没有指定长度,则采用默认 值,即变量数值的余数。如果两个数字(偏移量和长度)都是负数, 使用的数字则是环境变量数值长度加上指定的偏移量或长度。 %PATH:~-10% 会提取 PATH 变量的最后十个字符。 %PATH:~0,-2% 会提取 PATH 变量的所有字符,除了最后两个。 终于添加了延迟环境变量扩充的支持。该支持总是按默认值被 停用,但也可以通过 CMD.EXE 的 /V 命令行开关而被启用/停用。 请参阅 CMD /? 考虑到读取一行文本时所遇到的目前扩充的限制时,延迟环境 变量扩充是很有用的,而不是执行的时候。以下例子说明直接 变量扩充的问题: set VAR=before if "%VAR%" == "before" ( set VAR=after if "%VAR%" == "after" @echo If you see this, it worked ) 不会显示消息,因为在读到第一个 IF 语句时,BOTH IF 语句中 的 %VAR% 会被代替;原因是: 它包含 IF 的文体,IF 是一个 复合语句。所以,复合语句中的 IF 实际上是在比较 "before" 和 "after",这两者永远不会相等。同样,以下这个例子也不会达到 预期效果: set LIST= for %i in (*) do set LIST=%LIST% %i echo %LIST% 原因是,它不会在目前的目录中建立一个文件列表,而只是将 LIST 变量设成找到的最后一个文件。这也是因为 %LIST% 在 FOR 语句被读取时,只被扩充了一次;而且,那时的 LIST 变量 是空的。因此,我们真正执行的 FOR 循环是: for %i in (*) do set LIST= %i 这个循环继续将 LIST 设成找到的最后一个文件。 延迟环境变量扩充允许您使用一个不同的字符(惊叹号)在执行 时间扩充环境变量。如果延迟的变量扩充被启用,可以将上面 例子写成以下所示,以达到预期效果: set VAR=before if "%VAR%" == "before" ( set VAR=after if "!VAR!" == "after" @echo If you see this, it worked ) set LIST= for %i in (*) do set LIST=!LIST! %i echo %LIST% 如果命令扩展被启用,有几个动态环境变量可以被扩展,但 不会出现在 SET 显示的变量列表中。每次变量数值被扩展时, 这些变量数值都会被动态计算。如果用户用这些名称中任何 一个定义变量,那个定义会替代下面描述的动态定义: %CD% - 扩展到当前目录字符串。 %DATE% - 用跟 DATE 命令同样的格式扩展到当前日期。 %TIME% - 用跟 TIME 命令同样的格式扩展到当前时间。 %RANDOM% - 扩展到 0 和 32767 之间的任意十进制数字。 %ERRORLEVEL% - 扩展到当前 ERRORLEVEL 数值。 %CMDEXTVERSION% - 扩展到当前命令处理器扩展版本号。 %CMDCMDLINE% - 扩展到调用命令处理器的原始命令行。 C:\>for /? 对一组文件中的每一个文件执行某个特定命令。 FOR %variable IN (set) DO command [command-parameters] %variable 指定一个单一字母可替换的参数。 (set) 指定一个或一组文件。可以使用通配符。 command 指定对每个文件执行的命令。 command-parameters 为特定命令指定参数或命令行开关。 在批处理程序中使用 FOR 命令时,指定变量请使用 %%variable 而不要用 %variable。变量名称是区分大小写的,所以 %i 不同于 %I. 如果命令扩展被启用,下列额外的 FOR 命令格式会受到 支持: FOR /D %variable IN (set) DO command [command-parameters] 如果集中包含通配符,则指定与目录名匹配,而不与文件 名匹配。 FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters] 检查以 [drive:]path 为根的目录树,指向每个目录中的 FOR 语句。如果在 /R 后没有指定目录,则使用当前 目录。如果集仅为一个单点(.)字符,则枚举该目录树。 FOR /L %variable IN (start,step,end) DO command [command-parameters] 该集表示以增量形式从开始到结束的一个数字序列。 因此,(1,1,5) 将产生序列 1 2 3 4 5,(5,-1,1) 将产生 序列 (5 4 3 2 1)。 FOR /F ["options"] %variable IN (file-set) DO command [command-parameters] FOR /F ["options"] %variable IN ("string") DO command [command-parameters] FOR /F ["options"] %variable IN ('command') DO command [command-parameters] 或者,如果有 usebackq 选项: FOR /F ["options"] %variable IN (file-set) DO command [command-parameters] FOR /F ["options"] %variable IN ("string") DO command [command-parameters] FOR /F ["options"] %variable IN ('command') DO command [command-parameters] filenameset 为一个或多个文件名。继续到 filenameset 中的 下一个文件之前,每份文件都已被打开、读取并经过处理。 处理包括读取文件,将其分成一行行的文字,然后将每行 解析成零或更多的符号。然后用已找到的符号字符串变量值 调用 For 循环。以默认方式,/F 通过每个文件的每一行中分开 的第一个空白符号。跳过空白行。您可通过指定可选 "options" 参数替代默认解析操作。这个带引号的字符串包括一个或多个 指定不同解析选项的关键字。这些关键字为: eol=c - 指一个行注释字符的结尾(就一个) skip=n - 指在文件开始时忽略的行数。 delims=xxx - 指分隔符集。这个替换了空格和跳格键的 默认分隔符集。 tokens=x,y,m-n - 指每行的哪一个符号被传递到每个迭代 的 for 本身。这会导致额外变量名称的分配。m-n 格式为一个范围。通过 nth 符号指定 mth。如果 符号字符串中的最后一个字符星号, 那么额外的变量将在最后一个符号解析之后 分配并接受行的保留文本。 usebackq - 指定新语法已在下类情况中使用: 在作为命令执行一个后引号的字符串并且一个单 引号字符为文字字符串命令并允许在 filenameset 中使用双引号扩起文件名称。 某些范例可能有助: FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k 会分析 myfile.txt 中的每一行,忽略以分号打头的那些行,将 每行中的第二个和第三个符号传递给 for 程序体;用逗号和/或 空格定界符号。请注意,这个 for 程序体的语句引用 %i 来 取得第二个符号,引用 %j 来取得第三个符号,引用 %k 来取得第三个符号后的所有剩余符号。对于带有空格的文件 名,您需要用双引号将文件名括起来。为了用这种方式来使 用双引号,您还需要使用 usebackq 选项,否则,双引号会 被理解成是用作定义某个要分析的字符串的。 %i 专门在 for 语句中得到说明,%j 和 %k 是通过 tokens= 选项专门得到说明的。您可以通过 tokens= 一行 指定最多 26 个符号,只要不试图说明一个高于字母 'z' 或 'Z' 的变量。请记住,FOR 变量是单一字母、分大小写和全局的;而且, 同时不能有 52 个以上都在使用中。 您还可以在相邻字符串上使用 FOR /F 分析逻辑;方法是, 用单引号将括号之间的 filenameset 括起来。这样,该字符 串会被当作一个文件中的一个单一输入行。 最后,您可以用 FOR /F 命令来分析命令的输出。方法是,将 括号之间的 filenameset 变成一个反括字符串。该字符串会 被当作命令行,传递到一个子 CMD.EXE,其输出会被抓进 内存,并被当作文件分析。因此,以下例子: FOR /F "usebackq delims==" %i IN (`set`) DO @echo %i 会枚举当前环境中的环境变量名称。 另外,FOR 变量参照的替换已被增强。您现在可以使用下列 选项语法: ~I - 删除任何引号("),扩展 %I %~fI - 将 %I 扩展到一个完全合格的路径名 %~dI - 仅将 %I 扩展到一个驱动器号 %~pI - 仅将 %I 扩展到一个路径 %~nI - 仅将 %I 扩展到一个文件名 %~xI - 仅将 %I 扩展到一个文件扩展名 %~sI - 扩展的路径只含有短名 %~aI - 将 %I 扩展到文件的文件属性 %~tI - 将 %I 扩展到文件的日期/时间 %~zI - 将 %I 扩展到文件的大小 %~$PATH:I - 查找列在路径环境变量的目录,并将 %I 扩展 到找到的第一个完全合格的名称。如果环境变量名 未被定义,或者没有找到文件,此组合键会扩展到 空字符串 可以组合修饰符来得到多重结果: %~dpI - 仅将 %I 扩展到一个驱动器号和路径 %~nxI - 仅将 %I 扩展到一个文件名和扩展名 %~fsI - 仅将 %I 扩展到一个带有短名的完整路径名 %~dp$PATH:I - 搜索列在路径环境变量的目录,并将 %I 扩展 到找到的第一个驱动器号和路径。 %~ftzaI - 将 %I 扩展到类似输出线路的 DIR 在以上例子中,%I 和 PATH 可用其他有效数值代替。%~ 语法 用一个有效的 FOR 变量名终止。选取类似 %I 的大写变量名 比较易读,而且避免与不分大小写的组合键混淆。
迷之程序员 2018-04-11
  • 打赏
  • 举报
回复
小弟菜鸟,具体的代码实现还是不会..
迷之程序员 2018-04-11
  • 打赏
  • 举报
回复
引用 11 楼 DelphiGuy 的回复:
批处理就几行的事情还写程序 保存以下文本到一个.bat(name改成你需要的文件名,或者作为命令行参数%1、%2之类的输入): @echo off set MAX_NUM=0 for /f "tokens=2 delims=_." %%i in ('dir /b /-p name_*.zip') do if /I "%MAX_NUM%" lss "%%i" set /a MAX_NUM=%%i 2>nul echo name_%MAX_NUM%.zip set MAX_NUM=
我需要自动提取每种文件名称啊..
迷之程序员 2018-04-11
  • 打赏
  • 举报
回复
引用 8 楼 yiyefangzhou24 的回复:
批处理就能实现了,整个程序,忽略开发周期??
我也想到了用批处理,怎么弄?我现在只会把文件名排个序
  • 打赏
  • 举报
回复
批处理就几行的事情还写程序 保存以下文本到一个.bat(name改成你需要的文件名,或者作为命令行参数%1、%2之类的输入): @echo off set MAX_NUM=0 for /f "tokens=2 delims=_." %%i in ('dir /b /-p name_*.zip') do if /I "%MAX_NUM%" lss "%%i" set /a MAX_NUM=%%i 2>nul echo name_%MAX_NUM%.zip set MAX_NUM=
AlbertS 2018-04-11
  • 打赏
  • 举报
回复
比如先找到 TapCffexQtGw_SP13_121.zip就认为他是最大的,提取出最后的数字, 然后遍历剩下的文件,名字相同,如果数字有更大的就文件就删除当前的,否则删除新的,如果名字不同就把不同名字的文件作为新文件数字数字的最大的,继续遍历 这样假设一共有N种文件,则只需要遍历一次,但是需要花费O(N)的空间
自信男孩 2018-04-10
  • 打赏
  • 举报
回复
引用 5 楼 baidu_39486224 的回复:
[quote=引用 3 楼 cfjtaishan 的回复:] 按照文件名排序,或者通过遍历文件名列表得到字符串最大的。 "123"小于"132", 可以使用strcmp比较。
不是全部之中最大的,而是“每一种”找出最大的[/quote] 那可以分别找出有几类文件,比如通过比较_前的字符串,可以确定有多少类文件。然后再通过两次比较,第一次比较是找到所属的类(strncmp),第二次比较是比较该类的文件中最大的。
wallesyoyo 2018-04-10
  • 打赏
  • 举报
回复
这个是Python实现的代码。


import sys, os, shutil

if (len(sys.argv) != 3):
    print ("USAGE:\n\t%s + <in dir> + <out dir>\n" % sys.argv[0])
    exit(-1)

indir = sys.argv[1]
outdir = sys.argv[2]

if not os.path.exists(indir):
    print ("ERROR: %s No such directory!\n" % indir)
    exit(-1)

if not os.path.exists(outdir):
    os.mkdir(outdir)

d = {}

for fn in os.listdir(indir):
    name, ext = os.path.splitext(fn)
    if ext == ".zip":
        ns = name.split("_")
        name = ns[0]
        for n in ns[1:-1]:
            name += "_%s" % n
        num = int(ns[-1])
        
        if name in d:
            if d[name] < num:
                d[name] = num
        else:
            d[name] = num

for k,v in d.items():
    fn = k + "_" + str(v) + ".zip"
    sp = os.path.join(indir, fn)
    dp = os.path.join(outdir, fn)
    shutil.copyfile(sp, dp)
    print (dp)
    
运行的话,安装python3,在命令行上敲下面的命令就行。

python tt.py <indir> <outdir>
tt.py 是python代码文件名,indir是输入的目录,outdir是输出目录,程序就是把indir中符合条件的文件拷贝到outdir中。 像这种文件处理的操作,用python做起来真的特别简单,代码也是通俗易懂,你可以尝试学习一下。
迷之程序员 2018-04-10
  • 打赏
  • 举报
回复
引用 3 楼 cfjtaishan 的回复:
按照文件名排序,或者通过遍历文件名列表得到字符串最大的。 "123"小于"132", 可以使用strcmp比较。
不是全部之中最大的,而是“每一种”找出最大的
迷之程序员 2018-04-10
  • 打赏
  • 举报
回复
引用 2 楼 wanggui2015 的回复:
这种需求用脚本语言做不是分分钟就搞定了,Python了解一下。
这...刚弄懂一些批处理,脚本从没接触过...
自信男孩 2018-04-10
  • 打赏
  • 举报
回复
按照文件名排序,或者通过遍历文件名列表得到字符串最大的。 "123"小于"132", 可以使用strcmp比较。
wallesyoyo 2018-04-10
  • 打赏
  • 举报
回复
这种需求用脚本语言做不是分分钟就搞定了,Python了解一下。
paschen 版主 2018-04-10
  • 打赏
  • 举报
回复

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧