标题: [文本处理] 批处理如何对指定行数的文本进行分割排列 [打印本页]
作者: Rasm 时间: 2020-5-24 23:53 标题: 批处理如何对指定行数的文本进行分割排列
本帖最后由 Rasm 于 2020-5-25 23:01 编辑
原始文本 1.txt- 1005495524----a111111
- 1005495524----abc123
- 1005495524----aini1314
- 1005495524----iloveyou
- 1005495524----q1w2e3r4
- 1005495524----qq123123
- 1044122462aa----a111111
- 1044122462aa----abc123
- 1044122462aa----aini1314
- 1044122462aa----iloveyou
- 1044122462aa----q1w2e3r4
- 1044122462aa----qq123123
- 1095591332aa----a111111
- 1095591332aa----abc123
- 1095591332aa----aini1314
- 1095591332aa----iloveyou
- 1095591332aa----q1w2e3r4
- 1095591332aa----qq123123
- 1111qqqq1111----a111111
- 1111qqqq1111----abc123
- 1111qqqq1111----aini1314
- 1111qqqq1111----iloveyou
- 1111qqqq1111----q1w2e3r4
- 1111qqqq1111----qq123123
- 111qqq111----a111111
- 111qqq111----abc123
- 111qqq111----aini1314
- 111qqq111----iloveyou
- 111qqq111----q1w2e3r4
- 111qqq111----qq123123
复制代码
想将相同的内容,以每3行为基础进行分割,排列,实现以后的效果
处理后的文本 2.txt- 1005495524----aini1314
- 1005495524----a111111
- 1005495524----abc123
- 1044122462aa----aini1314
- 1044122462aa----a111111
- 1044122462aa----abc123
- 1095591332aa----aini1314
- 1095591332aa----a111111
- 1095591332aa----abc123
- 1111qqqq1111----aini1314
- 1111qqqq1111----a111111
- 1111qqqq1111----abc123
- 111qqq111----aini1314
- 111qqq111----a111111
- 111qqq111----abc123
- 1005495524----q1w2e3r4
- 1005495524----iloveyou
- 1005495524----qq123123
- 1044122462aa----q1w2e3r4
- 1044122462aa----iloveyou
- 1044122462aa----qq123123
- 1095591332aa----q1w2e3r4
- 1095591332aa----iloveyou
- 1095591332aa----qq123123
- 1111qqqq1111----q1w2e3r4
- 1111qqqq1111----iloveyou
- 1111qqqq1111----qq123123
- 111qqq111----q1w2e3r4
- 111qqq111----iloveyou
- 111qqq111----qq123123
复制代码
作者: went 时间: 2020-5-25 09:53
没看出你是怎么个排列法
作者: Rasm 时间: 2020-5-25 22:53
回复 2# went
就是 同一个用户名,以3行为分界线
作者: smss 时间: 2020-5-26 09:27
本帖最后由 smss 于 2020-5-26 09:33 编辑
- @echo off&setlocal EnableDelayedExpansion
- for /f "delims=" %%a in ('dir/b/s *.txt') do (set /a m=0,n=0
- for /f "usebackq delims=" %%i in ("%%a") do (set /a n=n%%3+1,m+=1
- if !m! equ 1 (>"%%a" echo %%i) else (>>"%%a" echo %%i
- if !n! equ 3 echo -------------------------我是分割线------------------------->>"%%a"
- )))
- echo 处理完毕
- pause
复制代码
作者: xczxczxcz 时间: 2020-5-26 10:31
回复 4# smss
你这个和一楼的结果是不一样的< 应该是把所有的用户数读3行,输出,再读所有用户的另外3行,再。。。
作者: flashercs 时间: 2020-5-26 11:03
- @echo off
- cd /d "%~dp0"
- set "srcfile=1.txt"
- set "dstfile=2.txt"
- set "tmpfile1=%temp%\~a.tmp"
- set "tmpfile2=%temp%\~b.tmp"
- cd .>"%tmpfile1%"
- cd .>"%tmpfile2%"
- setlocal EnableDelayedExpansion
- set tmpflag=0
- set line=0
- for /f "usebackq delims=" %%A in ("%srcfile%") do (
- set /a line+=1
- set str!line!=%%A
- if !line! equ 3 (
- if !tmpflag! equ 0 (
- >>%tmpfile1% (echo,!str3!&echo,!str1!&echo,!str2!)
- set tmpflag=1
- ) else (
- >>%tmpfile2% (echo,!str2!&echo,!str1!&echo,!str3!)
- set tmpflag=0
- )
- set line=0
- )
- )
- endlocal
- copy /y /b "%tmpfile1%"+"%tmpfile2%" "%dstfile%"
- del "%tmpfile1%"
- del "%tmpfile2%"
- pause
- exit /b
复制代码
作者: went 时间: 2020-5-26 11:12
6行数据为一组,输出顺序为3 1 2 5 4 6,应该就是这个规律- @echo off
- set "num=0"
- for /f "delims=" %%i in (1.txt) do (
- set /a "num+=1"
- call set "line%%num%%=%%i"
- )
- (
- set /a a=3,b=1,c=2
- call :loop
- set /a a=5,b=4,c=6
- call :loop
- )>2.txt
- pause&exit
-
- :loop
- call echo %%line%a%%%
- call echo %%line%b%%%
- call echo %%line%c%%%
- set /a a+=6,b+=6,c+=6
- if %a% leq %num% goto :loop
复制代码
作者: xczxczxcz 时间: 2020-5-26 11:42
回复 7# went
如果各用户的行数不一致,并不是所有的都6行的话,这个脚本输出不正确。
作者: xczxczxcz 时间: 2020-5-26 11:45
回复 6# flashercs
发现 这个也是要求各用户数的行数要一致,否则输出不正确,某个用户数会连续超过3行。
作者: xczxczxcz 时间: 2020-5-26 11:49
本帖最后由 xczxczxcz 于 2020-5-26 13:15 编辑
bat 版 不按一楼的顺序 大文件不知内存会不会爆- @echo off & cd /d "%~dp0"
- SetLocal EnableDelayedExpansion
-
- for /f "delims=" %%a in ('type ".\1.txt"^|sort') do (
- for /f "tokens=1 delims=-" %%b in ("%%a") do (
- if not defined \%%b (
- set /a n=1, m=1
- set "\%%b=%%b"
- ) else (
- set /a n+=1, mod=!n! %% 3
- if !mod! equ 0 set /a m+=1
- )
- set "##!m!#%%a=%%a"
- )
- )
- (for /f "tokens=2 delims==" %%a in ('set ##') do echo %%a)>2.txt
复制代码
作者: went 时间: 2020-5-26 11:50
回复 8# xczxczxcz
主要就是楼主这个规律有点蛋疼
作者: xczxczxcz 时间: 2020-5-26 12:21
powershell 版- $g = (gc '.\1.txt') | Group { $_ -replace '-.*$' };
- $(for ($i = 0; $i -lt ($g | sort { $_.Count } | select -last 1).Count; $i += 3) {$g | % { $_.Group[$i..($i + 2)] }}) | sc '.\2.txt' -force;
复制代码
作者: Gin_Q 时间: 2020-5-26 14:16
本帖最后由 Gin_Q 于 2020-5-26 14:35 编辑
我想Python的字典解决这个问题要简单很多!后面的排列好像需要是每个用户不能超过3行,不知道是需要满足多少行后可以再次重复第一次那个用户?(还是说把所有的满足3行的用户输出1遍(3行)(输出后销毁输出的3行),循环,)不满足条件后放到最后一起输出
作者: xczxczxcz 时间: 2020-5-26 14:26
回复 13# Gin_Q
你写个 PY 的 我写个纯PS的,看 PS 快 还 PY 快。 都用字典写
作者: Gin_Q 时间: 2020-5-26 14:31
回复 14# xczxczxcz
朋友,我对Python不熟练,我写的代码没有意义的!
作者: xczxczxcz 时间: 2020-5-26 14:48
回复 15# Gin_Q
不是熟不熟的问题, 纯PS 体质上 就比 PY 快些,都是脚本语言,PY 就是少打点字,少些括号,被国内媒体炒做太夸张。不如多点时间去学习 汇编/C系列/JAVA/Delphi等。
作者: Gin_Q 时间: 2020-5-26 14:53
回复 16# xczxczxcz
或许吧!!!我喜欢Python,就像喜欢C一样!
作者: Rasm 时间: 2020-5-27 23:35
回复 8# xczxczxcz
你好,我文本的原始数据,各用户的行数是一致的
作者: Rasm 时间: 2020-5-27 23:45
回复 7# went
如果我有20行用户名呢,用你这个就不行了吧
作者: Rasm 时间: 2020-5-28 00:27
回复 6# flashercs
如果所有的用户用户名有30行,该怎么写
作者: Rasm 时间: 2020-5-28 00:32
回复 5# xczxczxcz
你的思路是对的,他们写的,没有考虑到我如果同一个用户名有30行,就无法实现
作者: Rasm 时间: 2020-5-28 21:37 标题: 批处理如何对指定行数的文本进行分割排列
原始文本 1.txt- 1005495524----a111111
- 1005495524----abc123
- 1005495524----aini1314
- 1005495524----iloveyou
- 1005495524----q1w2e3r4
- 1005495524----qq123123
- 1044122462aa----a111111
- 1044122462aa----abc123
- 1044122462aa----aini1314
- 1044122462aa----iloveyou
- 1044122462aa----q1w2e3r4
- 1044122462aa----qq123123
- 1095591332aa----a111111
- 1095591332aa----abc123
- 1095591332aa----aini1314
- 1095591332aa----iloveyou
- 1095591332aa----q1w2e3r4
- 1095591332aa----qq123123
- 1111qqqq1111----a111111
- 1111qqqq1111----abc123
- 1111qqqq1111----aini1314
- 1111qqqq1111----iloveyou
- 1111qqqq1111----q1w2e3r4
- 1111qqqq1111----qq123123
- 111qqq111----a111111
- 111qqq111----abc123
- 111qqq111----aini1314
- 111qqq111----iloveyou
- 111qqq111----q1w2e3r4
- 111qqq111----qq123123
复制代码
处理后的文本2.txt- 1005495524----aini1314
- 1005495524----a111111
- 1005495524----abc123
- 1044122462aa----aini1314
- 1044122462aa----a111111
- 1044122462aa----abc123
- 1095591332aa----aini1314
- 1095591332aa----a111111
- 1095591332aa----abc123
- 1111qqqq1111----aini1314
- 1111qqqq1111----a111111
- 1111qqqq1111----abc123
- 111qqq111----aini1314
- 111qqq111----a111111
- 111qqq111----abc123
- 1005495524----q1w2e3r4
- 1005495524----iloveyou
- 1005495524----qq123123
- 1044122462aa----q1w2e3r4
- 1044122462aa----iloveyou
- 1044122462aa----qq123123
- 1095591332aa----q1w2e3r4
- 1095591332aa----iloveyou
- 1095591332aa----qq123123
- 1111qqqq1111----q1w2e3r4
- 1111qqqq1111----iloveyou
- 1111qqqq1111----qq123123
- 111qqq111----q1w2e3r4
- 111qqq111----iloveyou
- 111qqq111----qq123123
复制代码
想将相同的内容用户名,以每3行为基础进行分割,排列,实现2.txt的效果
附上原始文本,80万条,不知道批处理可否实现
链接:https://share.weiyun.com/KY7VFOde 密码:i4aayw
作者: cfwyy77_bat 时间: 2020-5-29 09:43
纯P, 估计累的够呛,这种文本需求,建议还是用其它语言来处理,如PS,python,perl,awk.
我个人现在还是更喜欢awk来处理文本。
简单起见,假定你的源文件,都是这样规则的,用户都已经分组好了,用户条数都是一致的。
test.awk- function ceil(a,b)
- {
- t=int(a/b)
- return a==t*b?t:t+1
- }
- BEGIN {
- usrLines=44
- n=3
- }
- {
- a[int((NR-1)/usrLines)][(NR-1)%usrLines]=$0
- }
- END {
- for(k=0;k<ceil(usrLines,n);k++)
- for(i=0;i<length(a);i++)
- for(j=0+n*k;j<n+n*k && j<usrLines;j++)
- print a[i][j]
- }
复制代码
- awk -f test.awk 3.txt >2.txt
复制代码
几十万条结果还是秒出的。
作者: Rasm 时间: 2020-5-29 19:40
本帖最后由 Rasm 于 2020-5-29 19:49 编辑
回复 23# cfwyy77_bat
为什么处理以后,有些是 4行,有些6行
附上原始文本,80万条
链接:https://share.weiyun.com/KY7VFOde 密码:i4aayw
作者: WHY 时间: 2020-5-30 16:15
本帖最后由 WHY 于 2020-6-12 16:38 编辑
- $d = get-Date;
- $arr = [IO.File]::ReadAllLines('3.txt', [Text.Encoding]::UTF8) -match '-{4}';
- $Len = $arr.Count;
- $dic = New-Object 'System.Collections.Generic.Dictionary[string, [Collections.ArrayList]]';
- $max = 0;
-
- for($i=0; $i -lt $Len; $i++) {
- $a = $arr[$i].Trim() -split('----');
- if( !$dic.ContainsKey($a[0]) ){
- $dic.Add($a[0], @($a[1])); #用户名加入到字典,密码加入到数组
- } else {
- [void]$dic[$a[0]].Add($a[1]);
- }
- }
-
- forEach($key In $dic.Keys) { #找长度最大的数组
- if($dic[$key].Count -gt $max){ $max = $dic[$key].Count; }
- }
-
- $out = for($i=0; $i -lt $max; $i+=3) {
- forEach($key In $dic.Keys) {
- for($j=0; $j -lt 3; $j++) {
- if($dic[$key].Count -gt $i+$j) {
- $key + '----' + $dic[$key][$i+$j];
- } else { break; }
- }
- }
- }
-
- [IO.File]::WriteAllLines('22.txt', $out);
- ((get-Date) - $d).TotalSeconds
- pause
复制代码
2.6404314
按 Enter 键继续...:
563024 行,速度不算快,也不算太慢- @echo off
- chcp 65001 > nul
- gawk -F"-{3,}" "BEGIN{max=0}{if($1!=s){i++;j=1};a[i][j++]=$0;s=$1;if(j>max)max=j}END{for(n=1;n<max;n+=3)for(i in a)for(j=0;j<3;j++)if(a[i][n+j])print a[i][n+j]}" 3.txt > 22.txt
- pause
复制代码
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |