[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文本处理] [已解决]批处理如何删除前几个字符相同的行?

本帖最后由 lsxq 于 2013-5-12 20:56 编辑

323.456.789.561
323.456.789.542
323.456.789.798
323.456.789.256

981.651.654.681
981.651.654.682

593.658.651.658

能否利用SED或者文本编辑器(类似EditPlus)删除“前几个字符相同的行”,行很多,前几个字符相同的行也很多。这里比如要删除前11个字符相同的所有行,

结果只剩下593.658.651.658这一行。
1

评分人数

    • Batcher: 感谢给帖子标题标注[已解决]字样PB + 2

回复 21# BAT-VBS

好的,谢谢提醒。

TOP

回复 20# lsxq


    问题解决后,请编辑顶楼帖子在标题前面注明[已解决],并给回答者加分。

TOP

回复 19# terse


彻底服了,测试没有问题。真是太牛了。万分感谢啊。

TOP

本帖最后由 terse 于 2013-5-12 19:03 编辑

GAWK 文本打乱问题
刚刚的有问题
改为循环试
  1. gawk -F. "{c[NR]=$1 FS $2 FS $3;n[c[NR]]++;a[c[NR]]=$0} END{for(i=1;i<=NR;i++) if (n[c[i]]==1) print a[c[i]]}" a.txt
复制代码
1

评分人数

    • lsxq: 乐于助人技术 + 1

TOP

本帖最后由 terse 于 2013-5-12 17:28 编辑
额滴神啊,先谢谢大家了。这段代码的处理速度最快。也用GAWK测试了下,结果发现 文本的排序被打乱了。但是速 ...
lsxq 发表于 2013-5-12 16:03

如确认为固定四段 这样可以快点
虽然 扩展为文件名可以使代码更简练 但效率不一样 至少我这里是这样
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "tokens=1-3* delims=." %%i in (a.txt) do if defined $%%i.%%j.%%k (set $%%i.%%j.%%k=1) else set "$%%i.%%j.%%k=0"
  3. (for /f "tokens=1-3* delims=." %%i in (a.txt) do if "!$%%i.%%j.%%k!" == "0" echo %%i.%%j.%%k.%%l)>b.txt
  4. pause
复制代码

TOP

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=" %%i in (a.txt) do (
  3.     set str=%%i&set "str=!str:~,11!"
  4.     set /a "$!str:~,11!+=1"
  5. )
  6. for /f "delims=" %%i in (a.txt) do (
  7.     set str=%%i
  8.     for %%j in ("!str:~,11!") do if "!$%%~j!" == "1" echo %%i
  9. )
  10. pause
复制代码
  1. gawk "{t=substr($0,0,10);n[t]++;a[t]=$0} END{for(m in n) if (n[m]<=1) print a[m]}" a.txt
复制代码
额滴神啊,先谢谢大家了。这段代码的处理速度最快。也用GAWK测试了下,结果发现 文本的排序被打乱了。但是速度比 这段批处理 还要快。不知道这个能不能解决。

在这个需要处理的 文本中,这些数字不一定都是15位的。像下面这种情况:

323.456.789.561
323.456.789.542
323.456.789.798
323.456.789.256

981.651.654.681
981.651.654.682

456.55.45.11
456.55.45.2

47.66.15.123
47.66.15.113

593.658.651.658

可以想象成4段,只要是 前3段的数字相同 就删除。

TOP

回复 15# terse
测试文本
  1. (for /l %%a in (1000,1,9000) do echo 111.22.%%a.333)>1.txt
复制代码
我是用下面这个测的
  1. :: 别忘了在代码开头加一句set t=%time%
  2. call :time0 "%t%" "%time%" "ok"
  3. echo.&echo 耗时: %ok%
  4. pause&exit
  5. :time0  以下为封装部分。
  6. :: code 随风 @bbs.bathone.cn 2008-08-15
  7. setlocal&set /a n=0
  8. for /f "tokens=1-8 delims=.: " %%a in ("%~1:%~2") do (
  9.    set /a n+=10%%a%%100*360000+10%%b%%100*6000+10%%c%%100*100+10%%d%%100
  10.    set /a n-=10%%e%%100*360000+10%%f%%100*6000+10%%g%%100*100+10%%h%%100
  11. )
  12. set "n=%n:-=%"
  13. set /a s=n/360000,n=n%%360000,f=n/6000,n=n%%6000,m=n/100,n=n%%100
  14. set "ok=%s% 小时 %f% 分钟 %m% 秒 %n% 毫秒"
  15. endlocal&set "%~3=%ok%"&goto :eof
复制代码
初学BAT,非专业。代码不适当之处还望前辈们多多指点。在此表示感谢!

TOP

回复 14# xxpinqz
难道测试数据不一样 差距这么大?
硬件也不会相差这么多吧
我这里测试 5W行数据都不过 5s 的

TOP

12楼这代码,高手啊,快的不是那么一点点。
测了个8000行文本
2楼VBS代码大约在1s23左右,12楼第一个gawk代码5ms(不过会乱序了),第3个代码37s左右
小文本vbs和gawk相差无几.
至于5楼的代码嘛,可以直接忽略了,除非8000行前11位都一样的,这个运行时间才好意思写出来
学到很多~~谢谢2楼12楼
初学BAT,非专业。代码不适当之处还望前辈们多多指点。在此表示感谢!

TOP

回复 11# apang
是那个意思,这个set /a 很好使啊,学习了~
初学BAT,非专业。代码不适当之处还望前辈们多多指点。在此表示感谢!

TOP

文件大的话 用外部比较好
外部 GAWK
  1. gawk "{t=substr($0,0,11);n[t]++;a[t]=$0} END{for(m in n) if (n[m]<=1) print a[m]}" a.txt
复制代码
如钟情BAT 有点吃力 看文件大小
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=" %%i in (a.txt) do (
  3.     set str=%%i&set "str=!str:~,11!"
  4.     if not defined #!str! (
  5.        set/a"n+=1"
  6.        set #!str!=#&set "$!n!=%%i"
  7.     ) else set "#!str!=$"
  8. )
  9. for /l %%i in (1 1 !n!) do (
  10.     set str=!$%%i!
  11.     for %%j in ("!str:~,11!") do if !#%%~j!# ==## echo !$%%i!
  12. )
  13. pause
复制代码
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=" %%i in (a.txt) do (
  3.     set str=%%i&set "str=!str:~,11!"
  4.     set /a "$!str:~,11!+=1"
  5. )
  6. for /f "delims=" %%i in (a.txt) do (
  7.     set str=%%i
  8.     for %%j in ("!str:~,11!") do if "!$%%~j!" == "1" echo %%i
  9. )
  10. pause
复制代码

TOP

回复 10# apang


    sorry,理解错误,if not defined %%~na 是为了减少findstr搜索的次数

TOP

回复 7# xxpinqz


    可以不用判断重复行的吧?重复行的话前面的11个字符也相同
  1. @echo off
  2. for /f "delims=" %%a in (1.txt) do (
  3.     set /a n=0
  4.     for /f "delims=" %%b in ('findstr /b "%%~na" 1.txt') do set /a n+=1
  5.     set /a "1/(n-1)" 2>nul||echo,%%a
  6. )
  7. pause
复制代码

TOP

楼主的意思是把有重复项去掉 而不是记录一次

TOP

返回列表