标题: [已解决]批处理命令for列举的项目如何去除重复内容? [打印本页]
作者: crist 时间: 2012-8-23 11:08 标题: [已解决]批处理命令for列举的项目如何去除重复内容?
本帖最后由 crist 于 2012-8-30 14:43 编辑
代码如下- @echo off
- pushd ~dp0
-
- title 还原Skype聊天记录
-
- if not exist "%ProgramFiles%\WinRAR\Rar.exe" goto error0
- set winrar=%ProgramFiles%\WinRAR\Rar.exe
-
- if exist "D:\Personal\My Documents\Skype\backup" (
- set source=D:\Personal\My Documents\Skype\backup
- ) else (
- set source=backup
- )
-
- :set_id
- cls
- echo 提示:1.任何时候若需中断操作都可直接关闭本程序窗口
- echo 2.备份前请先退出 Skype 程序
- echo 3.支持空格路径,不需要双引号
- echo.
- set "p=%userprofile%\Application Data\skype"
- if exist "%p%" (
- echo 目标路径下检测到以下 Skype 用户名:
- echo.
- for /f "delims=" %%a in ('dir /ad /b /s "%p%\chatsync"') do (
- if exist "%%~dpamain.db" if exist "%%~dpaconfig.xml" (
- for %%b in ("%%a\..") do echo %%~nxb
- )
- )
- ) else (
- echo 未检测到任何 Skype 用户记录
- echo 备份列表中存在以下用户名:
- if exist "%source%\*_*.zip" for /f "delims=_ tokens=1" %%i in ('dir/a/b/o "%source%\*_*.zip"') do echo %%i
- )
复制代码
由于备份列表中一个用户存在多个备份文件,因此代码运行后同一个用户名会被列举多次,请问如何让同一个用户名只列举一次呢?
问题已经解决,不过还有很多东西需要慢慢消化,感谢apang大侠的代码以及他耐心的讲解
作者: apang 时间: 2012-8-23 14:59
将下面的代码替换第33行的内容- if exist "%source%\*_*.zip" (
- for /f "delims=_" %%i in ('dir /a-d/b/on "%source%\*_*.zip"') do (
- if not defined .%%i set .%%i=1&echo %%i
- )
- )
复制代码
作者: crist 时间: 2012-8-23 17:29
回复 2# apang
这代码太神奇了,能讲解一下吗?
作者: 狗屁不通 时间: 2012-8-23 21:00
复制代码
作者: crist 时间: 2012-8-24 11:58
回复 4# 狗屁不通
以我的脑袋如果if /?能看懂就不用上网求助大侠了
作者: 狗屁不通 时间: 2012-8-24 12:32
回复 5# crist
if not defined .%%i set .%%i=1&echo %%i
如果存在%%i 则定义%%i =1并且显示%%i
作者: apang 时间: 2012-8-24 14:12
2楼未考虑用户名本身包含"_"字符的情况,假设有用户名ab_c,zip文件ab_c_1.zip,列表时会出错。
还是替换第33行的内容,试试:- if exist "%source%\*_*.zip" (
- setlocal enabledelayedexpansion
- for /f "delims=" %%i in ('dir /a-d/b/on "%source%\*_*.zip"') do (
- set "N=%%i"
- for %%j in ("!N:_=" "!") do set "name=!N:_%%~j=!"
- if not defined .!name! set .!name!=1&echo !name!
- )
- endlocal
- )
复制代码
作者: forfiles 时间: 2012-8-24 18:13
回复 3# crist
批处理删除重复行的常见用法
http://www.bathome.net/thread-5219-1-1.html
http://www.bathome.net/thread-5509-1-1.html
http://www.bathome.net/thread-4690-1-1.html
http://www.bathome.net/thread-5326-1-1.html
作者: crist 时间: 2012-8-25 17:02
回复 7# apang
测试通过,这代理真是博大精深,我是完全看不懂
谢谢大侠的代码
作者: crist 时间: 2012-8-25 17:04
回复 6# 狗屁不通
定义%%i=1,这里的1是用于选择第一个存在的%%i吗?有没有可能存在定义%%i=某个字母而不是某个数字的情况?如果有,那么定义为字母的意思是什么?
作者: forfiles 时间: 2012-8-25 18:08
回复 10# crist
你可以自己改成某个字母试试,然后再回来问。
作者: apang 时间: 2012-8-25 20:31
回复 9# crist
7#简单解释:
假设有ab_c_1.zip和ab_c_2.zip两个文件
for循环第一次,变量N被赋值为ab_c_1.zip
"!N:_=" "!"是将所有的下划线替换成双引号对(引号中间带空格)
就成这样子:for %%j in ("ab" "c" "1.zip") do set "name=!N:_%%~j=!"
再将字串ab_c_1.zip分别去掉_ab、_c、_1.zip后的结果赋值给变量name
最终name值为ab_c
if not defined .!name! set .!name!=1&echo !name! 意思是:
如果变量.ab_c未定义,将变量.ab_c赋值为1(其它字符也可以的)并显示变量name的值:ab_c
此时变量.ab_c未曾定义,if条件为真,set .!name!=1&echo !name!将被执行
for循环第二次,变量N被赋值为ab_c_2.zip
同1,最终name也被赋值为ab_c
此时变量.ab_c已被定义(前面被赋值为1),if条件为假,set .!name!=1&echo !name!不被执行
ab_c也就不再显示,达到只显示一次的效果
作者: crist 时间: 2012-8-27 16:44
回复 12# apang
首先我尝试了echo !N!,输出的是ab_c_1.zip,不懂的地方在下面
一个是set "name=!N:_%%~j=!"这句
(我在这行后面加上 &&echo !name! &&echo %%j输出的结果如下
ab_c_1.zip
"ab"
ab_1.zip
"c"
ab_c
"1.zip"
但是我看不懂这段代码是如何实现这个功能的,我被!和%和~等符号搞晕了)
然后通过if not defined .!name! set .!name!=1&echo !name!这段代码输出了以上全部结果中符合实际情况的一个就是ab_c
(为何!name!前面要加.?另外一个比较弱智的疑问是%name%在什么情况下要写成!name!)
作者: apang 时间: 2012-8-28 12:41
回复 13# crist
好吧,再试着解释下:- @echo off&setlocal enabledelayedexpansion
- set N=ab_c_1.zip
- for %%j in ("ab" "c" "1.zip") do set "name=!N:_%%~j=!"
- echo,!name!&pause
复制代码
for共循环三次:
1.将%%j赋值为"ab",%%~j值为ab,!N:_%%~j=!即!N:_ab=!(将N值中的_ab替换为空)
因为ab_c_1.zip不包含_ab,所以name值为ab_c_1.zip
2.将%%j赋值为"c",%%~j值为c,!N:_%%~j=!即!N:_c=!(将N值中的字串_c替换为空)
所以name值为ab_1.zip
3.将%%j赋值为"1.zip",%%~j值为1.zip,!N:_%%~j=!即!N:_1.zip=!(将N值中的_1.zip替换为空)
所以name值为ab_c
虽然3次循环都set name=..,但name最终取的是for最后一次(第3次)的set name=..的值
这跟set a=1&set a=2&set a=3&echo !a!最后显示的a值为3道理一样
开启变量延迟后,变量引用符%用!替代。也就是说,加上setlocal enabledelayedexpansion语句后,
将%name%改写成!name!
"为何!name!前面要加."?加不加.都可以,只是偶习惯加上了,避免!name!值为空时if语句报错
作者: crist 时间: 2012-8-29 17:17
本帖最后由 crist 于 2012-8-29 17:22 编辑
回复 14# apang
渐渐看懂了,唯独开头一句“将%%j赋值为"ab",%%~j值为ab”这句没明白,我试着加入了一句echo %%~j,结果回显是%~j
以上是我echo的位置不对导致回显错误的
后来改成- @echo off&setlocal enabledelayedexpansion
- set N=ab_c_1.zip
- for %%j in ("ab" "c" "1.zip") do echo %%~j&pause &&set "name=!N:_%%~j=!"
- echo,!name!&pause
复制代码
发现%%~j回显确实如您所说
而直接echo %%j则回显内容有双引号"",这是为什么呢?(这个问题会不会太弱?)
作者: apang 时间: 2012-8-29 21:16
回复 15# crist
%%~j就是对变量%%j的扩展,删除引号的意思。
楼主可自行搜索相关教程,讲的很全的。。。
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |