中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
« [1] [2] »
作者:
标题: 怎么去除TXT文件中重复的行 上一主题 | 下一主题
a9319751
中级用户





积分 439
发帖 170
注册 2006-1-9
状态 离线
『楼 主』:  怎么去除TXT文件中重复的行

如题,可以用DOS命令实现吗?

FC ?

2006-2-4 18:53
查看资料  发送邮件  发短消息 网志  OICQ (5040366)  编辑帖子  回复  引用回复
a9319751
中级用户





积分 439
发帖 170
注册 2006-1-9
状态 离线
『第 2 楼』:  

怎么删除TXT中相同的行

2006-2-4 19:06
查看资料  发送邮件  发短消息 网志  OICQ (5040366)  编辑帖子  回复  引用回复
a9319751
中级用户





积分 439
发帖 170
注册 2006-1-9
状态 离线
『第 3 楼』:  

Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adCmdText = &H0001

Set objConnection = CreateObject("ADODB.Connection")
Set objRecordSet = CreateObject("ADODB.Recordset")

strPathToTextFile = "C:\Scripts\"
strFile = "Test.txt"

objConnection.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
      "Data Source=" & strPathtoTextFile & ";" & _
          "Extended Properties=""text;HDR=NO;FMT=Delimited"""

objRecordSet.Open "Select DISTINCT * FROM " & strFile, _
    objConnection, adOpenStatic, adLockOptimistic, adCmdText

Do Until objRecordSet.EOF
    Wscript.Echo objRecordSet.Fields.Item(0).Value   
    objRecordSet.MoveNext
Loop

2006-2-4 20:10
查看资料  发送邮件  发短消息 网志  OICQ (5040366)  编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 4 楼』:  

  请问楼主,你要删除所有的重复行还是对重复了N次的行只保留其中的一行?删除之后,不同行的相对位置还要保持不变吗?



尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2006-9-5 08:42
查看资料  发短消息 网志   编辑帖子  回复  引用回复
vkill
金牌会员





积分 4103
发帖 1744
注册 2006-1-20
来自 甘肃.临泽
状态 离线
『第 5 楼』:  

假如你的文件是 a.txt

cd.>a_temp.txt
for /f "tokens=1 delims=," %%i in (a.txt) do (find a_temp.txt "%%i" && echo.>nul||echo %%i>>a_temp.txt)

生成新文件a_temp.txt 文件就是了,我在改一个东西的时候想到用的

[ Last edited by he200377 on 2006-9-6 at 03:15 ]

2006-9-6 03:13
查看资料  发送邮件  访问主页  发短消息 网志   编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 6 楼』:  

Re he200377:

  事情没那么简单,你这个代码还有很多缺陷:

  1、当后面有N行内容与第一行相同时,第一行的内容并不能被过滤掉;

  2、当把一个文件的内容复制一次再接在原来的行后的话,输出的内容为复制之前的内容。也就是说,当文件内所有行都有重复N次的时候,还会打印1/N行的内容;

  3、delims=, 这个分隔符有何依据?只用find而不用findstr的正则表达式,会把很多行中含有 %%i 字符串的行过滤掉;

  4、echo %%i>>a_temp.txt这一句中会把原文件里行首的所有空格都去掉,也就是说不能保留原行的格式;

  要实现过滤重复行的操作,还有很多情况是需要考虑的,并且,由于CMD对某些字符敏感,无论代码编写得如何完美,还是不能在所有场合中都适用。

  最近也在思考这个问题该如何处理,也和论坛上的一些朋友探讨过,目前已经有了比较成熟的方案,正在除错的测试过程中。如果楼主能回答我在4楼提出的问题,那么,对我现在这个代码的完善就有了更好的帮助了。

[ Last edited by namejm on 2006-9-6 at 04:53 ]



尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2006-9-6 04:30
查看资料  发短消息 网志   编辑帖子  回复  引用回复
vkill
金牌会员





积分 4103
发帖 1744
注册 2006-1-20
来自 甘肃.临泽
状态 离线
『第 7 楼』:  

Re namejm

1、当后面有N行内容与第一行相同时,第一行的内容并不能被过滤掉;
#可以的啊

2、当把一个文件的内容复制一次再接在原来的行后的话,输出的内容为复制之前电脑内容。也就是说,当文件内所有行都有重复N次的时候,还会打印1/N行的内容;
#不明白

3、delims=, 这个分隔符有何依据?只用find而不用findstr的正则表达式,会把很多行中含有%%i字符串的行过滤掉;
#这到是,没有想到,应该用findstr /v   ,delims=,这里可以看情况改改,我直接复制过来也没有看

4、echo %%i>>a_temp.txt这一句中会把原文件里行首的所有空格都去掉,也就是说不能保留原行的格式;
#这确实不能保留原行的格式

2006-9-6 04:42
查看资料  发送邮件  访问主页  发短消息 网志   编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 8 楼』:  

Re he200377『第 8 楼』:  

  1、当你构造如a.txt所示的文本来测试就知道不可以了;

  2、用如b.txt所示的文本测试一下就明白了。

a.txt
dos
china
dos
dos
bat
dos
b.txt
dos
china
bat
dos
china
bat
dos
china
bat




尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2006-9-6 04:51
查看资料  发短消息 网志   编辑帖子  回复  引用回复
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『第 9 楼』:  


───────────────── 版务记录 ─────────────────
执行:Will Sort
操作:移动主题:自 DOS疑難解答 & 問題討論(解答室)
说明:按照新的版区分划方案,本主题更适合于发表在此版区
───────────────── 版务记录 ─────────────────


[ Last edited by willsort on 2006-9-13 at 23:21 ]



※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2006-9-9 11:15
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 10 楼』:  

  如果楼主是要把所有相同内容的行都删掉的话,可以用如下代码(本来想把各个功能都完善一下的,现在只做了个半成品):
@echo off
:: mode con lines=25
:: 解决问题的思路:
:: 比较相邻三行的内容
:: 如果前两行内容相等,并且与第三行不相等,则取第二行的内容放入repetition.txt
:: 如此循环
:: 跳出for之后
:: 如果最后一行和倒数第二行内容相等,则把最后一行内容放入repetition.txt
:: 最后,用for从repetition.txt中逐行读出信息,在原文件中把这些信息过滤掉
:: 行首的空格将被忽略,空行将不被删除(且不纳入统计数据)
:: 效率惊人地高

:: 不能处理的符号有:
:: 管道符号:|
:: 连接符号:&、&&、||
:: 重定向符号:<、<<、>、>>
:: 转义符号:^
:: 其他字符:"、;、:、\(但是在行首是可以的)

:: 弊端:
:: findstr不能搜索过长的字符串(长度是多少?)

:: Code by JM,Thanks to NaturalJ0
:: build on 2006-9-4~2006-9-
:: 还要完善或者开发的功能:
:: 对无用的临时文件的处理;统计被过滤的行数;操作时的提示;适应各种文件名;

cls
title 相同行内容过滤器-处理中...
call :blank
call :blank
echo                          正在处理,请耐心等待...
:: 做程序开始时间标记
set time_begin=%time:~0,-3%
for /f "tokens=1,2,3 delims=:" %%i in ("%time_begin%") do (
    set /a hour_b=%%i
    set /a munite_b=%%
    set /a second_b=%%
)

set lines_total=0
set count_same=0
>sort.txt sort<test.txt
cd.>repetition.txt
setlocal enabledelayedexpansion
for /f "tokens=*" %%i in (sort.txt) do (
    set first=!second!
    set second=!third!
    set third=%%i
    set /a lines_total+=1
    call :comp_
)
:: 当%second%未取到值的时候,要避免repetition.txt记录echo的状态
if not "%second%"=="" if "%second%"=="%third%" >>repetition.txt echo %third%&& set /a count_same+=1
:: 没有重复内容则不对原文件作过滤处理
findstr . repetition.txt>nul||(del /q repetition.txt & goto :result)
copy test.txt test.bak>nul
for /f "tokens=*" %%i in (repetition.txt) do (
    findstr /v "\<%%i\>" test.txt>>tmp.txt
    del /q test.txt
    ren tmp.txt test.txt
)
:result
for /f "tokens=*" %%i in (test.txt) do (
    set /a lines_spare+=1
)
if "%lines_spare%"=="" set lines_spare=0
:: 当文本内容超过3行,且存在用相同个数的空格为内容的行时
:: repetition.txt会记录echo的状态,会导致统计不准确
:: 所以还要用通过比较处理前后行数是否相同来校正统计数据
if "%lines_total%"=="%lines_spare%" (del /q repetition.txt&set count_same=0)
set /a lines_del=%lines_total%-%lines_spare%
cls
title 相同行内容过滤器-过滤结果
call :blank
echo ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
echo                   原文件共有 %lines_total% 行;共有 %count_same% 条重复记录.(未计算空行)
echo                   处理后的文件还剩 %lines_spare% 行.(未计算空行)
echo                   被删除的内容总计 %lines_del% 行

rem ======计算花费的时间========
set time_end=%time:~0,-3%
for /f "tokens=1,2,3 delims=:" %%i in ("%time_end%") do (
    set /a hour_e=%%
    set /a munite_e=%%j
    set /a second_e=%%k
)
call :time_lapse
echo                   耗时: %hour_% 小时 %munite_% 分 %second_% 秒.
echo.
echo                   test.txt为处理后的文件;test.bak为原始文件的备份
echo                   sort.txt为原始文件内容的排序文件,你可以很方便地
echo               查看文本内容重复与否及重复情况;
echo                   repetition为重复行的内容,升序排列;若原始文本没
echo               有重复行,则此文件不存在.
echo ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
call :blank
echo                                                                 按任意键退出...
pause>nul
goto :eof

:comp_
:: 当%second%或者三个变量全都取到空值的时候,要避免repetition.txt记录echo的状态
if not "%first%"=="" (
  if not "%second%"=="" (
    if "%second%"=="%first%" (
      if not "%second%"=="%third%" >>repetition.txt echo %second%&& set /a count_same+=1
    )
  )
)
goto :eof

rem =====计算运行程序花费的时间========
:time_lapse
:: 一定要按照 秒=>分钟=>小时 的顺序操作
if %second_e% lss %second_b% (
    set /a munite_e=%munite_e%-1
    set /a second_e=%second_e%+60
)
set /a second_=%second_e%-%second_b%
if %munite_e% lss %munite_b% (
    set /a hour_e=%hour_e%-1
    set /a munite_e=%munite_e%+60
)
set /a munite_=%munite_e%-%munite_b%
if %hour_e% lss %hour_b% (
    set /a hour_e=%hour_e%+24
)
set /a hour_=%hour_e%-%hour_b%
goto :eof

:blank
echo.
echo.
echo.
echo.
goto :eof




尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2006-9-13 11:23
查看资料  发短消息 网志   编辑帖子  回复  引用回复
a9319751
中级用户





积分 439
发帖 170
注册 2006-1-9
状态 离线
『第 11 楼』:  

to:willsort
我冤枉啊,斑竹大人,我是半年前发贴求救的,半年前还没这个板块的,我不是故意发错地方的。

2006-9-13 11:40
查看资料  发送邮件  发短消息 网志  OICQ (5040366)  编辑帖子  回复  引用回复
a9319751
中级用户





积分 439
发帖 170
注册 2006-1-9
状态 离线
『第 12 楼』:  

to:namejm
谢谢你半年后还能帮我找到这个帖子,并且帮我写出脚本,测试中

我打算半一个文本A.TXT中重复的行删除后,得到B.TXT

A

CHINA
   DOS

   DOS

cn    dos
BBS
CHINA



B
CHINA
   DOS
cn    dos
BBS

[ Last edited by a9319751 on 2006-9-13 at 11:56 ]

2006-9-13 11:43
查看资料  发送邮件  发短消息 网志  OICQ (5040366)  编辑帖子  回复  引用回复
a9319751
中级用户





积分 439
发帖 170
注册 2006-1-9
状态 离线
『第 13 楼』:  



  Quote:
Originally posted by he200377 at 2006-9-6 03:13:
假如你的文件是 a.txt

cd.>a_temp.txt
for /f "tokens=1 delims=," %%i in (a.txt) do (find a_temp.txt "%%i" && echo.>nul||echo %%i>>a_temp.txt)

生栮..

谢谢你的回复,测试不错,但是未测试特殊字符

[ Last edited by a9319751 on 2006-9-13 at 11:59 ]

2006-9-13 11:52
查看资料  发送邮件  发短消息 网志  OICQ (5040366)  编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 14 楼』:  

  如果楼主只是想把重复N次的行打印一次,并且无须保持行的相对位置不变的话,可以参考bagpipe曾经写过的一段代码:

  排序,过滤相同行(简单批处理)

[ Last edited by namejm on 2006-9-13 at 12:03 ]



尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2006-9-13 12:01
查看资料  发短消息 网志   编辑帖子  回复  引用回复
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『第 15 楼』:  

Re a9319751『第 11 楼』:

      很抱歉,我的操作失误给你带来了负面影响,对此我郑重表示道歉!

      现已对原处理方式作出纠正,望周知。



※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2006-9-13 23:25
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
« [1] [2] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: