简体   繁体   English

grep的替代品,用于隔离Windows命令行中的特定文本

[英]Alternative to grep for isolating specific text in Windows command line

My network changes rather dynamically and unfortunately I am forced to run Windows. 我的网络变化很大,很不幸,我被迫运行Windows。

This script works because I have installed GNU tools for Windows and can use grep. 该脚本有效,因为我已经为Windows安装了GNU工具并且可以使用grep。

I would like to be able to run this script on any windows machine without having to install anything (grep etc). 我希望能够在任何Windows计算机上运行此脚本,而无需安装任何东西(grep等)。 I used findstr in this at first but could not get it to show only what matches the regex string. 首先,我在其中使用了findstr,但无法使其仅显示与正则表达式字符串匹配的内容。

@echo off

set %IPLIST% = nul
Echo.
Echo "Pinging all local Gateways"
    ipconfig | findstr /i "Gateway" | grep -o "[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*" > %IPLIST%

For /F "Usebackq Delims=" %%# in ("%IPLIST%") 
do (
    Echo+
    Echo [+] Pinging: %%#

Ping -n 1 "%%#" 1>nul && (
    Echo     [OK]) || (
    Echo     [FAILED])
)

Echo.
Echo.

Echo "now testing your internet connection"
Echo .
Echo ...

if %errorlevel% == 0 (
    echo ....you're all good bro.
) else (
    ping -n 3 "8.8.8.8" | findstr /r /c:"[0-9] *ms"
    if %errorlevel% == 1 (
echo ....all is lost
)
)
Echo.

You have a number of problems with the script. 脚本有很多问题。

set %IPLIST% = nul

This would yield a syntax error because iplist is likely undefined, and you are attempting to set the variable contents of iplist to "nul" 这将产生语法错误,因为iplist可能未定义,并且您尝试将contents of iplist的变量contents of iplist设置为“ nul”

The resolution of this would be 解决的办法是

set  = nul

Further, spaces on either side of the = are included in the variable/value set, so removing the % s would set the value of iplist Space to Space nul 此外, =两侧的空格都包含在变量/值集中,因此删除% s会将iplist Space的值设置为Space nul

Had iplist indeed been set up to nul then your ipconfig command would have simply dumped its eventual output into the bit-bucket as it would have been sent to nul . 如果确实将iplist设置为nul那么您的ipconfig命令将其最终输出像发送到nul一样简单地转储到了位桶中。

For /F "Usebackq Delims=" %%# in ("%IPLIST%") 

The do ( must be on the same physical line as the "for" do (必须与“ for”位于同一物理行

<opinion>Using non-alphas as metavariables is not a good idea as it is not officially supported <\opinion>

if %errorlevel% == 0 (
    echo ....you're all good bro.
) else (
    ping -n 3 "8.8.8.8" | findstr /r /c:"[0-9] *ms"
    if %errorlevel% == 1 (
echo ....all is lost
)
)

Because of the delayed expansion trap (all %var% in a block (parenthesised sequence of statements) are replaced by their value at parse-time ) the innermost %errorlevel% here would be replaced by whatever errorlevel was set to when the outermost if was encountered. 由于的delayed expansion trap (所有%var%在语句块(parenthesised序列)在分析时可以通过值被替换)的最内%errorlevel%这里将由任何替换errorlevel被设置为当最外if是遇到。 To interpret the ping output, you'd need to either invoke delayedexpansion (many, many SO items on this subject) or use the old original if errorlevel n... construct, where the if condition is true if the current errorlevel is n or greater than n . 要解释ping输出,您需要调用delayedexpansion (此主题上有很多SO项目),或使用旧的if errorlevel n...构造,如果当前错误errorleveln ,则if条件为true或大于n

So - reconstructing using batch features, 所以-使用批处理特征进行重建

@ECHO OFF
SETLOCAL

Echo.
Echo "Pinging all local Gateways"
For /F "tokens=2 Delims=:" %%a in ('ipconfig ^| findstr /i "Gateway"') DO IF "%%a" neq " " (
    Echo+
    Echo [+] Pinging: %%a

Ping -n 1 %%a 1>nul && (
    Echo     [OK]) || (
    Echo     [FAILED])
)

Echo.
Echo.

Echo "now testing your internet connection"
Echo .
Echo ...

if %errorlevel% == 0 (
    echo ....you're all good bro.
) else (
    ping -n 3 "8.8.8.8" | findstr /r /c:"[0-9] *ms"
    if ERRORLEVEL 1 IF NOT ERRORLEVEL 2 (
echo ....all is lost
)
)
Echo.
GOTO :EOF

The 'for /f tokenises the output of the command in single-quotes using : as a delimiter and picking the second token to apply to %%a`. 'for / f tokenises the output of the command in single-quotes usingas a delimiter and picking the second token to apply to tokenises the output of the command in single-quotes using as a delimiter and picking the second token to apply to tokenises the output of the command in single-quotes using as a delimiter and picking the second token to apply to %% a`。

The | | needs to be escaped by a caret to tell cmd that it is part of the command to be executed, not part of the for . 需要通过脱字符号转义以告诉cmd它是要执行的命令的一部分,而不是for一部分。

The for processes the output of ipconfig... so %%a has the form Spacexxx.xxx.xxx.xxx for处理ipconfig...的输出ipconfig...因此%%a的格式为Spacexxx.xxx.xxx.xxx

On my machine, xxx... was missing on one line, so I filtered out the single-space response. 在我的机器上, xxx...在一行中丢失,因此我过滤掉了单空格响应。

Pinging %%a without the quotes adds an extra space into the ping line, which is harmless. %%a 没有引号 %%a 情况下对 %%a 进行 ping操作会在ping行中添加额外的空间,这是无害的。 With the quotes, it didn't like it. 用引号,它不喜欢它。

Then the appendix... 然后是附录...

I'm not sure what you're really attempting here. 我不确定您在这里真正尝试了什么。 Perhaps it was a frustrated debug attempt. 也许这是一次沮丧的调试尝试。

errorlevel will be set to whatever the last ping result was. errorlevel将设置为last ping结果的结果。 This is logically unpredictable. 这在逻辑上是不可预测的。

I've shown a correct method of interpreting the findstr errorlevel result. 我已经展示了一种解释findstr级别结果的正确方法。 I'm not sure that your regex is correct here...but the all is lost message would only be shown if findstr sets errorlevel to 1. 我不确定您的正则表达式在这里是否正确...但是,仅当findstr将errorlevel设置为1时,才会显示all is lost消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM