windows批处理(shell)多行字符串匹配

本文介绍了一个批处理脚本,该脚本用于从指定文件中提取CREATE语句至分号结束的所有内容,并输出到另一文件中。文章详细展示了脚本的实现过程,包括如何处理特殊字符干扰及使用标志变量来跟踪匹配状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现从文件中截取出从一个字符串开始到另一个字符串结束,之间所有的字符输出到另一个文件中。下面的批处理脚本实现从1_DDL.out文件中将所有在CREATE和分号之间的行输出到0.txt中。(一个CREATE对应紧随其后的分号为一组)

@echo off
Rem matching and extracting the create table statements
if exist 1_DDL.out (
  echo now extracting create table statements
  set myflag=false
  SetLocal EnableDelayedExpansion
  for /f "delims=" %%i in (1_DDL.out) do (
    echo %%i
    
    echo %%i|find "CREATE">nul && set myflag=true
    if "!myflag!" == "true" (
      echo %%i >> 0.txt
      rem echo %%i
    ) else (
      echo not matching...
    )
    echo %%i|find ";">nul && set myflag=false
  )
) else (
  echo not found 1_DDL.out
)
Rem deleting the unused file
echo clearing the unused files
del 1_DDL.out
echo Done.

上述批处理代码,存在一个问题:当输入文件1_DDL.out中含有大于号>等特殊符号时,匹配失败,且会有各种“奇怪”的现象。大家有兴趣可以自己试验一下。下面是经过增强的版本2:

Rem matching and extracting the create table statements
if exist 1_DDL.out (
  echo now extracting create table statements
  set myflag=false
  rem any good idea?
  set tempflag=false
  SetLocal EnableDelayedExpansion
  for /f "delims=" %%i in (1_DDL.out) do (
    echo %%i
    rem tackling the > operator
    
    rem echo "%%i"
    set tempflag = false
    echo %%i |find ";">nul && set tempflag=true
    echo "%%i"|find /i "create">nul && set myflag=true
    echo !myflag!
    if "!myflag!" == "true" (
      echo %%i >> DDL.txt
      rem echo %%i
    ) else (
      echo not matching...
    )
    rem the next sentence do nth if there is a > in current %%i
    rem echo %%i|find ";">nul && set myflag=false
    if "!tempflag!" == "true" set myflag=false
  )
  endlocal
) else (
  echo not found 1_DDL.out
)

上面的实现用了两个flag变量,逻辑有点绕。特别注意一下%%i加了引号。下面是逻辑较为清晰的代码:

Rem matching and extracting the create table statements
if exist 1_DDL.out (
  echo now extracting create table statements
  set myflag=false
  SetLocal EnableDelayedExpansion
  for /f "delims=" %%i in (1_DDL.out) do (
    echo %%i
    rem tackling the > operator
	
    echo "%%i"
    echo "%%i"|find /i "create">nul && set myflag=true
    echo myflag !myflag!
    if "!myflag!" == "true" (
      echo %%i >> DDL.txt
      rem echo %%i
    ) else (
      echo not matching...
    )
    echo "%%i"|find ";">nul && set myflag=false
  )
  endlocal
) else (
  echo not found 1_DDL.out
)
今天(2012年11月26号)发现之前写的这个bat,
echo "%%i"|find /i "create">nul && set myflag=true

这行执行时会报错find: `create': No such file or directory或者The process tried to write to a nonexistent pipe,很诧异,之前执行都未出现此问题,google了一段时间没有找到解决办法。最后只能先改成findstr了。哪位大虾有解决办法共享下。


<think>好的,我现在要帮用户分析他们提供的批处理脚本。用户之前已经询问过类似的ADB命令脚本,所以可能他们正在开发或维护一个自动化测试流程,特别是涉及Android设备的电池状态和屏幕唤醒情况。首先,我需要仔细阅读用户提供的代码,理解每一行的作用,并确保我的解析准确无误。 首先,用户这次提供的脚本主要目标是打印电池状态和屏幕唤醒状态,并将相关信息记录到日志文件中。代码中包含了一些注释掉的命令,比如`::Print Battery Status`,这可能是一个标题,说明接下来的部分是关于电池状态的。接下来是几个adb命令和文件操作,最后还有之前提到的返回主屏幕的操作。 我需要先拆解每一行代码的作用。`adb -s %serial% wait-for-device`是确保设备连接成功,这在自动化脚本中很重要,避免后续命令因设备未连接而失败。接下来的`adb -s %serial% shell "dumpsys window | grep mAwake | sed 's/.*mAwake=\([^ ]*\).*/\1/'" >> screen.txt`这一行比较复杂,需要解析。这里用户通过dumpsys window获取窗口信息,然后用grep过滤出mAwake行,再用sed提取值,输出到screen.txt。可能用户想检查设备屏幕是否唤醒。 然后是`adb -s %serial% shell dumpsys battery > battery.txt`,这显然是将电池信息导出到battery.txt。接着用findstr查找电池的level,保存到battery_level.txt,然后用for循环提取具体数值,存入变量battery_level。之后将测试开始时间、日期和电池等级写入CSV日志文件。最后的timeout和adb返回主屏幕的命令之前已经解析过。 接下来需要考虑用户可能的深层需求。他们可能在做一个自动化测试,需要监控设备电池状态和屏幕状态,可能在测试过程中记录这些信息以分析设备的功耗情况。用户可能遇到的问题是权限问题,比如某些设备需要root权限才能获取dumpsys信息,或者adb连接不稳定。此外,脚本的兼容性也需要考虑,不同Android版本或厂商定制系统可能会有不同的输出格式,导致grep或sed命令失效。 例如,`dumpsys window`的输出在不同设备上可能不同,mAwake字段是否存在,或者格式是否一致,这会影响脚本的稳定性。另外,提取电池level的部分,使用findstr和for循环,是否在所有情况下都能正确提取数值?比如,如果battery.txt中有多行包含"level",可能会有问题。需要检查是否唯一匹配。 此外,用户可能希望将日志记录到CSV文件,方便后续分析,但当前的echo命令是否正确地生成CSV格式?比如日期和时间的格式是否有逗号,是否需要引号包裹。还有,变量battery_level在for循环中设置后,是否在同一个批处理会话中可用?因为批处理的变量作用域问题,如果在块内设置变量,可能需要启用延迟扩展。 在优化建议方面,可以考虑增加错误处理,比如检查adb命令是否执行成功,文件是否生成。另外,使用更健壮的方法提取数值,比如使用更精确的字符串处理,避免依赖特定输出格式。对于不同设备,可能需要条件判断来处理不同的dumpsys输出。 用户可能没有提到的需求包括自动化测试的扩展性,比如是否要循环多次检测电池状态,或者在测试结束后生成汇总报告。此外,时间戳的格式是否统一,CSV文件的头部是否每次都会被覆盖还是追加,这些细节可能影响后续数据处理。 总结来说,我需要将代码分解成各个部分,解释其功能,指出潜在问题,并提供优化建议,同时考虑用户可能的实际应用场景,帮助他们完善脚本的稳定性和兼容性。</think>以下是您提供的批处理脚本的逐层解析和功能说明: --- ### **一、核心功能总结** 该脚本通过ADB命令实现以下核心功能: 1. **捕获设备屏幕唤醒状态**(`mAwake`值) 2. **记录电池电量信息**(`level`值) 3. **生成带时间戳的电池日志文件** 4. **返回设备主屏幕** --- ### **二、关键代码解析** #### **1. 等待设备连接** ```batch adb -s %serial% wait-for-device ``` - **作用**:阻塞后续命令执行,直到目标设备通过ADB连接成功 - **必要性**:避免因设备未就绪导致后续命令失败 --- #### **2. 获取屏幕唤醒状态** ```batch adb -s %serial% shell "dumpsys window | grep mAwake | sed 's/.*mAwake=\([^ ]*\).*/\1/'" >> screen.txt ``` - **代码分解**: - `dumpsys window`:获取窗口管理系统服务信息 - `grep mAwake`:过滤出包含屏幕唤醒状态的字段(`true`/`false`) - `sed`:提取`mAwake`的具体布尔值 - `>> screen.txt`:追加写入屏幕状态记录文件 - **输出示例**: ```plaintext true # 表示屏幕处于唤醒状态 false # 表示屏幕已熄灭 ``` --- #### **3. 获取完整电池信息** ```batch adb -s %serial% shell dumpsys battery > battery.txt ``` - **输出内容**: ```plaintext Current Battery Service state: AC powered: false USB powered: true Wireless powered: false Max charging current: 500000 Max charging voltage: 5000000 Charge counter: 1234567 status: 2 health: 2 present: true level: 78 ← 重点关注值 scale: 100 voltage: 4321 temperature: 320 technology: Li-ion ``` --- #### **4. 提取电池电量百分比** ```batch findstr -i "level" battery.txt > battery_level.txt for /f "tokens=2 delims=: " %%G in (battery_level.txt) do ( set "battery_level=%%G" ) ``` - **流程说明**: 1. 从`battery.txt`中过滤出包含`level`的行 2. 使用`:`和空格作为分隔符,提取第二列数值(即电量百分比) 3. 将结果存入`battery_level`变量 --- #### **5. 生成日志文件** ```batch echo Test Start ,Start %date%,Test Start %time%,Starting Battery Level %battery_level% > battery_log.csv ``` - **输出格式**: ```csv Test Start ,Start 2024-03-15,Test Start 14:30:45.67,Starting Battery Level 78 ``` - **注意**:使用`>`会覆盖文件内容,如需追加应改为`>>` --- ### **三、完整执行流程** ```plaintext 开始 ↓ 等待设备连接 → 获取屏幕唤醒状态 → 保存到screen.txt ↓ 获取完整电池信息 → 提取电量百分比 → 生成CSV日志 ↓ 等待2秒 → 发送Home键返回主屏幕 ↓ 结束 ``` --- ### **四、潜在问题与优化建议** #### **1. 兼容性问题** - `mAwake`字段可能在某些定制ROM(如MIUI、OneUI)中不存在 - **验证方法**:手动执行`adb shell dumpsys window`查看输出 - `dumpsys battery`在不同Android版本中的输出格式可能变化 - **建议**:改用更稳定的`adb shell dumpsys batteryproperties` #### **2. 变量作用域问题** - 批处理脚本中`for`循环设置的变量可能无法正确传递 - **解决方案**:在脚本开头添加`setlocal enabledelayedexpansion` - **改进代码**: ```batch setlocal enabledelayedexpansion for /f ... do ( set "battery_level=%%G" ) echo !battery_level! ``` #### **3. 时间戳格式优化** - 默认`%date%`和`%time%`包含空格可能导致CSV解析错误 - **改进方案**: ```batch set "timestamp=%date:/=-%_%time::=-%" echo Test Start,%timestamp%,%battery_level% >> battery_log.csv ``` #### **4. 扩展监控功能** - 添加循环监控: ```batch :loop adb -s %serial% shell dumpsys battery >> battery.txt timeout /t 60 # 每分钟记录一次 goto loop ``` - 增加温度监控: ```batch findstr /i "temperature" battery.txt > battery_temp.txt ``` --- ### **五、典型应用场景** 1. **自动化测试**:在长时间压力测试中监控设备电量消耗 2. **故障诊断**:分析屏幕异常唤醒导致的耗电问题 3. **用户体验优化**:统计不同使用场景下的电量变化规律 如果需要进一步解释特定命令的实现原理,或需要构建完整的设备监控方案,请提供更多细节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值