标题: [文本处理] 批处理如何删除含A内容以上文本、及含B内容以下文本,保留中间的文本? [打印本页]
作者: kidzgy 时间: 2023-8-5 00:54 标题: 批处理如何删除含A内容以上文本、及含B内容以下文本,保留中间的文本?
本帖最后由 kidzgy 于 2023-8-5 21:03 编辑
- [删除的内容]
- [删除的内容]
- [删除的内容]
- Array.prototype.p = Array.prototype.push; [本行也删除]
-
- [保留的内容]
- [保留的内容]
- [保留的内容]
- [保留的内容]
- [保留的内容]
-
- delete(Array.prototype.p); [本行也删除]
- [删除的内容]
- [删除的内容]
- [删除的内容]
复制代码
须注意:【Array.prototype.p = Array.prototype.push; 】 【delete(Array.prototype.p); 】内容在全文搜索均仅有一个结果,如何删除【Array.prototype.p = Array.prototype.push; 】本行内容及以上的所有文本、【delete(Array.prototype.p); 】本行内容及以下的文本?且最终的效果是保留内容上下无空白行?
预期效果如下:- [保留的内容]
- [保留的内容]
- [保留的内容]
- [保留的内容]
- [保留的内容]
复制代码
测试文件:
由于压缩包超过50KB,无法上传至此,故用外链。测试文件系由Snap2HTML生成的html文件。
https://wwi.lanzoup.com/iUDU114kcw4j
我刚刚灵光一闪,换了个思路,发现【findstr /i "D.p([" %1 > "temp.html"】这样的方法即可提取出所需的内容。
由于生成多个的html是可以拼接的,还是很好奇,如何运用开始的思路来分离文本?
作者: 77七 时间: 2023-8-5 01:31
- @echo off
- rem 注意将代码中的两处字符串替换为文本中的整行,包含行首、尾空格(如有)。
- (for /f "useback delims=" %%a in ("1.txt") do (
- if "%%a" equ "delete(Array.prototype.p);" (
- goto :next
- )
- if defined n (
- echo %%a
- )
- if "%%a" equ "Array.prototype.p = Array.prototype.push;" (
- set n=1
- )
- ))>"2.txt"
- :next
- pause
复制代码
作者: hfxiang 时间: 2023-8-5 09:24
回复 1# kidzgy
可试一下第3方工具sed ( http://bcn.bathome.net/tool/4.9/sed.exe )- sed -n -r "/^Array\.prototype\.p = Array\.prototype\.push\;/,/^delete\(Array\.prototype\.p\)\;/{/^$/d;/^Array\.prototype\.p = Array\.prototype\.push\;/d;/^delete\(Array\.prototype\.p\)\;/d;p}" a.txt>b.txt
复制代码
作者: wanghan519 时间: 2023-8-5 09:56
sed删除1到Array那一行,再删除delete到最后一行,也许可以- sed '1,/^Array/d;/^delete/,$d' a.txt
复制代码
作者: kidzgy 时间: 2023-8-5 13:53
77七 发表于 2023-8-5 01:31
回复 kidzgy
可试一下第3方工具sed ( )
hfxiang 发表于 2023-8-5 09:24
两个输出都是空白文件
作者: 77七 时间: 2023-8-5 14:24
回复 5# kidzgy
参考2楼代码第2行。
作者: Five66 时间: 2023-8-5 14:36
本帖最后由 Five66 于 2023-8-6 03:42 编辑
input.txt是输入文件名
output.txt是输出文件名
编码ascii- @if (0)//==(0)// echo off&pause&cscript //nologo -e:jscript "%~f0"&pause&exit
- @end
-
- var inf,otf,sstr,estr,s,bbb;
-
- inf="input.txt";
- otf="output.txt";
-
- sstr="Array.prototype.p = Array.prototype.push;";
- estr="delete(Array.prototype.p);";
-
- var fso=new ActiveXObject('scripting.filesystemobject');
- inf=fso.OpenTextFile(inf,1,false);
- otf=fso.OpenTextFile(otf,2,true);
-
- s='';bbb=0;
-
- while(!inf.AtEndOfStream){
- s=inf.ReadLine();
- if(s==estr){break;}
- if(bbb && s){otf.WriteLine(s);s='';}
- if(s==sstr){bbb=1;}
- }
-
- inf.Close();otf.Close();fso=null;
复制代码
作者: aloha20200628 时间: 2023-8-5 16:49
用sed.exe(本坛第三方下载)确实比用纯P轻爽 》先粗洗一遍源文,再掐头去尾...- @echo off
- set "p1=^Array.prototype.p = Array.prototype.push;$"
- set "p2=^delete(Array.prototype.p);"
- sed -n "/%p1%/, /%p2%/p" "源文件" | sed -e "/^$/d" -e "$d" -e "1d"
复制代码
作者: aloha20200628 时间: 2023-8-5 18:42
再给一个尽量简化的纯P版本,与近来数帖 '在界定行之间提取目标数据' 的题型均属同一套路...- @echo off
- set "p1=Array.prototype.p = Array.prototype.push;"
- set "p2=delete(Array.prototype.p);"
- set "got="
- for /f "delims=" %%s in (源文件) do (
- if /i "%%s"=="%p1%" (set "got=1") else if defined got (
- if /i "%%s"=="%p2%" (exit/b) else (echo,%%s)
- )
- )
复制代码
作者: Batcher 时间: 2023-8-5 20:47
回复 1# kidzgy
请把文件上传到网盘以便测试代码
作者: kidzgy 时间: 2023-8-5 21:00
回复 7# Five66
提示D:\Personal\Desktop\123.bat(19, 5) Microsoft JScript 运行时错误: 输入超出了文件尾
现在已在楼主层附上测试文件。
作者: jyswjjgdwtdtj 时间: 2023-8-5 21:16
- 'vbs
- set fso=createobject("scripting.filesystemobject")
- set r=new regexp
- sstr="Array.prototype.p = Array.prototype.push;"
- estr="delete(Array.prototype.p);"
- inf="input.txt";
- otf="output.txt";
- inf=fso.OpenTextFile(inf,1,false)
- otf=fso.OpenTextFile(otf,2,true)
- r.pattern=sstr&"(.*)"&estr
- r.multiline=true
- otf.write r.execute(inf.readall)(0).submatches(0)
复制代码
或许可以吧
作者: 77七 时间: 2023-8-5 23:17
test.html- var D = dirs;
- Array.prototype.p = Array.prototype.push;
-
- D.p(["D:/quest2*0*1680711711*D:/quest2/","CastReceiver_1.5.6_armeabi-v7a_by_Prosmart.by.apk*12505115*1618494146","SKYBOX v1.1.0.465.apk*140533455*1680486331","SKYBOX VR Video Player [1.1.0.525].apk*121507878*1647912077","ssrray-release-3.8.10.1.apk*36174974*1621004286",310721422,"1"])
- D.p(["D:/quest2/adb*0*1633840967","aapt.exe*1639424*1619405894","aapt_20210426105805.exe*1639424*1619405894","adb.exe*1974272*1619405894","adb_20210426105805.exe*1974272*1619405895","AdbWinApi.dll*97792*1619405894","AdbWinApi_20210426105805.dll*97792*1619405894","AdbWinUsbApi.dll*62976*1619405894","AdbWinUsbApi_20210426105808.dll*62976*1619405895",7548928,""])
-
-
-
- delete(Array.prototype.p); // remove alias added above
-
- $(document).ready(function(){
复制代码
code2
- @echo off
- chcp 65001 >nul
- rem 批处理保存为utf-8编码格式
- set "str1=Array.prototype.p = Array.prototype.push;"
- set "str2=delete(Array.prototype.p);"
- for /f "tokens=1 delims=:" %%a in ('^<"test.html" findstr /n /c:"%str1%" /c:"%str2%"') do (
- if not defined s (
- set s=%%a
- ) else (
- set e=%%a
- )
- )
- (for /f "tokens=1* delims=:" %%a in ('^<"test.html" findstr /n .') do (
- if %%a gtr %s% if %%a lss %e% (
- echo=%%b
- )
- ))>"out.html"
复制代码
作者: kidzgy 时间: 2023-8-5 23:55
回复 13# 77七
感谢解答,这个似乎有局限性,用楼主层的文件测试是没有问题的,因为处理的代码比较短,我用另外一个文件测试,会提示 FINDSTR: Line 772 is too long.
这个是新的测试文件:
https://wwi.lanzoup.com/imB4X14kr4kh
作者: kidzgy 时间: 2023-8-6 00:35
另外想请教个问题:- gawk -v "IGNORECASE=1" "{print $0=gensub(/quest2/,\"xyz\",\"g\")>\"test.html\"}" test.html
复制代码
我用上述代码,读取文件和生成文件指向同一个文件的时候,会导致内容缺失。不知道是什么原因?我有时候修改其他文件的时候倒没有这个问题。
或许可以吧
jyswjjgdwtdtj 发表于 2023-8-5 21:16
vbs代码执行时弹错。
作者: Five66 时间: 2023-8-6 01:08
回复 11# kidzgy
呃,测试文件是utf-8 bom编码的,而且换行符是LF,试试下面的
test.html为输入文件名
output.txt为输出文件名,输出文件编码跟换行符都跟测试文件一样的
代码保存为ansi就行了- #@&cls&pause&powershell "gc -literalpath '%~f0'|out-string|iex"&pause&exit
-
- $inf="test.html"
- $otf="output.txt"
-
- $sstr="Array.prototype.p = Array.prototype.push;"
- $estr="delete(Array.prototype.p);"
-
- $inf=[io.file]::OpenRead($pwd.path+"\$inf")
- $otf=[io.file]::OpenWrite($pwd.path+"\$otf")
-
- $infrd=[System.IO.StreamReader]::new($inf,[text.encoding]::UTF8)
- $otfwd=[System.IO.StreamWriter]::new($otf,[text.encoding]::UTF8)
- $otfwd.NewLine=("`n")
-
- $s='';$bbb=0;
-
- while(!$infrd.EndOfStream){
- $s=$infrd.ReadLine()
- if($s){
- $ss=$s.Trim()
- if(($ss.Length -ge $estr.Length) -and ($ss.SubString(0,$estr.Length) -eq $estr)){break;}
- if($bbb){$otfwd.WriteLine($s);$s='';}
- if(($ss.Length -ge $sstr.Length) -and ($ss.SubString(0,$sstr.Length) -eq $sstr)){$bbb=1;}
- }}
-
- $infrd.Close();$otfwd.Close()
复制代码
作者: wanghan519 时间: 2023-8-6 06:50
本帖最后由 wanghan519 于 2023-8-6 06:57 编辑
回复 15# kidzgy
awk不能输入输出指向同一个文件,除非使用-i inplace参数或者使用sponge命令,但单文件的gawk没有这些。。。
sed可以用-i参数,用例子试了sed -i '1,/^[[:blank:]]*Array/d;/^[[:blank:]]*delete/,$d;/^$/d' test.html
作者: qixiaobin0715 时间: 2023-8-6 08:58
在cmd中无论是设置环境变量或是循环变量,其变量值都有限制。
楼主的文件直接用命令(比如type)显示没有问题,如果将其与变量建立联系,一旦超出长度限制,代码就会将其忽略。比如14楼提供的文件中的第99行,由于长度过长而超限,如果在for循环中读取,循环变量%%I就会将其忽略,而继续读取下一行。
所以不能考虑使用纯P来处理。
作者: aloha20200628 时间: 2023-8-6 10:11
回复 14# kidzgy
订正8L的代码如下,用14L提供的新测试文件验证成功。- @echo off
- set "p1=Array.prototype.p = Array.prototype.push;"
- set "p2=delete(Array.prototype.p);"
- sed -n "/%p1%/, /%p2%/p" "test2.html" | sed -e "/^$/d" -e "$d" -e "1d">"test2.html.new"
复制代码
作者: kidzgy 时间: 2023-8-6 10:26
本帖最后由 kidzgy 于 2023-8-6 10:36 编辑
回复 17# wanghan519
在gawk使用 【-i inplace】参数时,即【gawk -i inplace '{ gsub(/foo/, "bar") }; { print }' "test.html"】,会提示以下:- gawk: fatal: cannot open source file `inplace' for reading: No such file or directory
复制代码
不知道是哪里出了问题
更正:
不好意思,原来akw 和gawk不是同一个东西的嘛,所以如果要直接修改源文件的话,只能用sed -i 了?
作者: kidzgy 时间: 2023-8-6 10:37
回复 16# Five66
回复 19# aloha20200628
感谢两位,经测试,非常完美!
作者: aloha20200628 时间: 2023-8-6 11:11
针对LZ提供的测试文件,其实不用下载第三方,直接用下式
findstr /LB "D.p(" "test2.html">"test2.html.new"
即可一步达成LZ所要结果(即使测试文件是utf-8编码,单行字符量远超8K) ... LZ是要求助有比其更'好'的方法吗? ...至今尚未看到...
作者: wanghan519 时间: 2023-8-6 12:13
回复 20# kidzgy
单文件的gawk.exe好像得输出到临时文件再覆盖回去,git for windows里面的gawk就能用,装上也不亏毕竟git还是比较常用的。。。
作者: kidzgy 时间: 2023-8-6 12:49
回复 22# aloha20200628
哈哈,其实我在楼主层末段已经说明了同样的方法。
作者: hfxiang 时间: 2023-8-6 13:10
回复 5# kidzgy
3楼的代码针对原1楼提供的测试样本测试是有效的。
现针对https://wwi.lanzoup.com/iUDU114kcw4j提供的测试样本,修改如下,经测试有效:- sed -n -r "/Array\.prototype\.p = Array\.prototype\.push\;/,/delete\(Array\.prototype\.p\)\;/{/^$/d;/Array\.prototype\.p = Array\.prototype\.push\;/d;/delete\(Array\.prototype\.p\)\;/d;p}" test.html>b.txt
复制代码
作者: jyswjjgdwtdtj 时间: 2023-8-6 13:12
回复 15# kidzgy
你看到分号就删一下呗
作者: 77七 时间: 2023-8-6 17:10
本帖最后由 77七 于 2023-8-6 17:14 编辑
文本行超长,批处理处理不了。要是我自己用的话,可以用第三方工具,linex和cfile ,都可以通过行号打印超长文本行。
打印第100行及接下来的10行
type 1.txt|linex -l 100 -e 10
linex -l 100 -e 10 <1.txt >2.txt
打印第100-110行
cfile 100,110 1.txt >2.txt
大概是这样。
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |