Board logo

标题: [文本处理] [已解决]批处理如何定时删除文本前50%内容? [打印本页]

作者: jzsgyml    时间: 2011-12-15 18:58     标题: [已解决]批处理如何定时删除文本前50%内容?

有个日志文件log.txt ,时刻都在写入日志信息。

现在要求,每隔2小时去删除该日志的前部分50%的信息。

流程大概就是“ 读取文本行数N(例如1000行)——删除前N/2(500行)并且覆盖原文本——等待2小时——goto start”
作者: CrLf    时间: 2011-12-15 19:52

  1. @echo off&setlocal enabledelayedexpansion
  2. if %1. neq . (
  3.    set "time=%~1"
  4.    for /f %%a in ('find /c /v ""^<log.txt') do set /a l=%%a/2
  5.    more +!l! log.txt>$
  6.    move /y $ log.txt
  7. )
  8. set /a next=(%time:~,2%+2)%%24
  9. set next= %next%
  10. at %next%:%time:~2,6% cmd /d /c @"%~f0" "%next:~-2%:%time:~2,6%"
复制代码

作者: Demon    时间: 2011-12-15 20:45

CrLf 发表于 2011-12-15 19:52


我一直很想问,为什么要用 if %1. neq . 这种“晦涩”的写法?
作者: CrLf    时间: 2011-12-15 20:50

回复 3# Demon


    因为比较省事啊,通用性也不太差,所以...
    晦涩了吗?没注意到,那下次还是用 if "%~1"=="" 吧
作者: Demon    时间: 2011-12-15 21:04

回复  Demon


    因为比较省事啊,通用性也不太差,所以...
    晦涩了吗?没注意到,那下次还是用  ...
CrLf 发表于 2011-12-15 20:50


个人觉得这种写法比较有可读性,也许是水平比较低的缘故。
作者: CrLf    时间: 2011-12-15 21:20

回复 5# Demon

每个人看法不一样吧,印象中 batman 和 qzwqzw 比较注重可读性这方面,对我来说,自打学批开始就一直是 效率>简洁>绿色>编写时间>可读性,除非以表达思路为主或者别人要求,否则一般情况下不太顾虑可读性,曾经就因为这个习惯被 qzw 批过,当时留意了一阵子,后来慢慢转移注意力了...
作者: wc726842270    时间: 2011-12-15 21:30

可读性却实很重要,如果没有好的习惯,别人很难和你和作。不过首先要先找到好的同伴。说了点费话。不过在不同的领域中符号可能代表不同的含义
作者: jellyhk    时间: 2011-12-16 10:30

回复 4# CrLf
if "%~1"==""
中的%~1这种写法是什么意思?为什么不是%1
作者: awk    时间: 2011-12-16 11:09

回复 8# jellyhk


%1里面可能包含双引号
作者: awk    时间: 2011-12-16 11:13

  1. @echo off
  2. gawk "{a[NR]=$0}END{for(i=1;i<NR/2;i++)print a[i]}" a.log >b.log
  3. move /y b.log a.log
复制代码

作者: Demon    时间: 2011-12-16 11:44

回复  Demon

每个人看法不一样吧,印象中 batman 和 qzwqzw 比较注重可读性这方面,对我来说,自打学批 ...
CrLf 发表于 2011-12-15 21:20


批处理是怎样我不知道,我只知道《C和指针》中有一句话:“不要为了效率上的细微差别而牺牲可读性。”

其实我觉得,批处理的效率再低,只要比手动操作要快,就是可以接受的。

不过来这里提问的人,大部分只是为了解决手中的问题,根本不会去阅读代码,所以可读性高或者低,其实并没有多大区别。
作者: CrLf    时间: 2011-12-16 13:27

本帖最后由 CrLf 于 2011-12-17 00:10 编辑

回复 8# jellyhk

回复 11# Demon


话说这个技巧学习自 plp626 的函数,因为简单实用而一直沿用了下来。
正如 awk 所说,有一部分是因为兼容空双引号的原因,曾纠结于一个问题,如何既能兼容空参数(即 "" 这样只有一对双引号的参数),又能兼容可能存在的特殊字符呢?不过当时感觉 call 没啥用,所以没有做进一步猜测和大量测试。
  1. @echo off
  2. call :test "" test 1
  3. call :test "" test 1
  4. pause
  5. :test
  6. echo if %1.==. echo k
  7. echo if "%~1"=="" echo k
  8. echo ----end----
复制代码
在 call 中,特殊字符是无法正常输出的(前阵子向 zqz 请教时得到的结果,丧气),也就是说,&、|、<、>这几个字符必须靠双引号转义输出,无法用 ^ 单独转义,而双引号无法单独输出、若要输出 % 与引号之外的转义符需要成倍的数量(二次扩展特性),还有让人无法理解的是 ^ 的数量居然会翻倍。
所以,call的时候不建议用转义符,也几乎不需要用转义符(除了正反括号 (、) 外,其余字符都仅能用双引号转义)。
这些问题应该是 cmd 接受 shell 参数时也存在的问题,测试过,用 ftype batfile="%1" %* ^& 修改关联方式,强制为 bat 文件添加特殊字符参数,结果同样存无法在引号对之法输出特殊字符的情况,似乎 cmd 遇到包含特殊字符的参数就六亲不认了,不过此时 ^ 倍增的情况倒是没有出现。
  1. @echo off
  2. call echo ^&
  3. call echo ^^^&
  4. call echo "&"
  5. ::特殊字符只能用双引号转义输出
  6. call echo "^"
  7. ::^ 的数量翻倍...
  8. call :test ^" 参数2
  9. call :test ^^^" 参数2
  10. call :test "" 参数2
  11. ::转义符无能
  12. pause&exit
  13. :test
  14. echo 参数1:[%1]
  15. echo 参数2:[%2]
复制代码
综上所述,if "%~1"=="" 与 if %1.==. 各有优势。
if "%~1"=="" 无法判断空参数,但兼容其余任何情况,所以适合在存在带有语法性质的未闭合括号情况下用,比如:
  1. call :test ()
  2. pause&exit
  3. :test
  4. for /l %%a in (1 1 5) do (
  5.    if "%~1" neq "" set /a n+=%%a
  6. )
  7. ::"%~1" 在参数为 () 时也不会导致语法错误,但是会把 "" 等同于空
复制代码
if %1.==. 其实不惧怕除了 ( 与 ) 之外的特殊字符,而且兼容空参数,所以适合用于不存在带有语法意义的未闭合括号情况下用,如:
  1. call :test ""
  2. pause&exit
  3. :test
  4. for /l %%a in (1 1 5) do if %1. neq . set /a n+=%%a
  5. ::%1. 能够判断 "",但是在参数为 () 时则可能导致语法错误
复制代码
前者是绝不会出语法错误的稳妥写法,后者是能判断任何类型参数但是需要推敲位置避免语法错误的写法,对一般的调用来说,前者比较简便不容易出错,而对于函数来说,后者确实是简洁通用的选择。

至于可读性,其实个人认为两种写法貌似差不多,只是前者频频出镜,大家看得眼熟了就比较好认,对不认识扩展参数的人看来,%~1 可能还更难理解呢。
我感觉代码的可读性似乎更多地体现在注释上,代码的可读性则要面对更多的人群,俗话说众口难调么,反而不好把握。所以吧,即使有可读性的需求,我也是以注释为主,代码上也没有考虑太多...
个人看法,哈哈




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2