我在文本文件中有以下数据,我想获取特定"Node name“的Hostname:
Node 1 entry:
Node name = NODE1
Comment =
Directory entry type = LOCAL
Protocol = TCPIP
Hostname = 192.168.100.1
Node 2 entry:
Node name = NODE2
Comment =
Directory entry type = LOCAL
Protocol = TCPIP
Hostname = 192.168.100.2
Node 3 entry:
Node name = NODE3
Comment =
Directory entry type = LOCAL
Protocol = TCPIP
Hostname = 192.168.100.3 示例:作为输入,我输入“节点名”,例如NODE2。然后我需要在NODE2下面搜索4行,并读取主机名为192.168.100.2。包含IP地址的行是我想要的结果。
在Linux上,这很简单:
grep -A 4 "NODE3" file.txt | grep Hostname注意:-A 4用于与搜索匹配的返回行和额外的4行
或者更好:
grep -A 4 "\<NODE3\>" file.txt | grep Hostname如果NODE3是名称的子字符串,如: NODE3A,则上述命令将仅严格搜索"NODE3“。
或者仅获取IP地址(第三列是列之间用一个或多个空格分隔):
grep -A 4 "\<NODE3\>" file.txt | grep Hostname | gawk '{print $3}'问:如何在Windows上使用Windows原生命令做同样的事情?
附注:此脚本将在多个Windows计算机上运行,我不想在Windows上安装额外的软件。我知道我可以安装grep和其他命令,但我不想这样做。解决方案必须使用Windows唯一的命令(Windows 7,Windows 2008和更新的应该是工作),因为脚本文件(批处理文件)将运行在几个不同的Windows版本,我不被允许安装软件,也不想分发其他额外的软件。
发布于 2017-07-11 18:57:12
尝尝这个
@echo off
set "skip="
set "host="
set "searchNode=NODE2"
for /F "tokens=1,* delims=[]" %%A in ('type file.txt ^| find /I /N "%searchNode%"') do (
if not defined skip set/a skip=%%A & goto :found
)
:found
if not defined skip echo/%searchNode% was not found. & exit/B
rem lines_to_skip = line_found + lines_below - 1
set /a skip+=3
for /F "skip=%skip% tokens=1,* delims=[]" %%A in ('type file.txt ^| find /N /V "^"') do (
for /F "tokens=1,* delims== " %%a in ("%%B") do set "host=%%b" & goto :stop
)
:stop
echo/%host%
exit/B首先,搜索文件,直到匹配到所需的字符串,并存储行号。然后,计算要跳过的行(我们搜索第四行,行号+4- 1)。最后,重新解析文件,只读取所需的行。
发布于 2017-07-11 19:17:00
对编辑进行了一些简化(去掉了一个If)
@Echo off&SetLocal EnableExtensions EnableDelayedExpansion
Rem pass Node name as Arg1 to this batch
Set "Node=" & Set "IP=not found"
For /F "tokens=1-3delims=:= " %%A in ('type file.txt') Do (
If /i "%%A%%B" Equ "Nodename" Set "Node=%%C"
IF /i "%%A%~1" Equ "Hostname!Node!" Set "IP=%%B"
)
Echo IP for Node %1 is %IP%样本输出
> SO_45031925.cmd Node2
IP for Node Node2 is 192.168.100.2
> SO_45031925.cmd Node1
IP for Node Node1 is 192.168.100.1
> SO_45031925.cmd Node3
IP for Node Node3 is 192.168.100.3
> SO_45031925.cmd Node4
IP for Node Node4 is not found附注:
在windows中使用grep和gawk时,只有单引号必须与双引号交换:
> grep -A 4 "\<NODE3\>" file.txt | grep Hostname | gawk "{print $3}"
192.168.100.3此PowerShell变体要求选择字符串仅出现在较新的Windows版本中。
$Node = 'Node3'
$IP = Select-String -Path .\file.txt -Pattern "Node name\s+= $Node" -Context 0,4 |
ForEach-Object {($_.Context.PostContext[3]).Split('=')[1].Trim()}
"IP for Node {0} is {1}" -f $Node,$IP发布于 2017-07-12 03:03:32
设计SETX command的目的是在cmd.exe环境中定义持久变量。但是,此命令具有一个不寻常且实际上未使用的功能,该功能允许从文本文件中提取位于其他项目相对位置的项目。最终效果类似于将FOR命令与FINDSTR命令相结合,但具有更多功能,并且以一种更简单的方式。
您希望在示例中获得的结果可以通过以下方式获得:
setx /F test.txt dummyVar /R 4,-1 NODE2在前一行中,/F test.txt部分指定要搜索的文件,dummyVar是要设置的持久变量。/R 4,-1 NODE2部分的意思是:“执行NODE2项目的/Relative搜索,找到后,返回位于下面4行和之前1项的项目”。"items“从零开始编号,默认以空格分隔,但您可以通过/D开关定义一系列分隔符(类似于for命令的"delims=”开关)。结果是这样展示的:
Extracted value: 192.168.100.2.因此,为了获得您想要的结果,您必须使用以下代码:
for /F "tokens=3" %%a in ('setx /F test.txt dummyVar /R 4^,-1 NODE2') do set "host=%%a" & goto continue
:continue
set "host=%host:~0,-1%"
echo %host%请注意,/R 4,-1部分中的逗号必须使用插入符号进行转义,并且结果在结尾处包含一个必须删除的附加点。
这种方法的一个小缺点是,dummyVar是在cmd.exe环境中永久定义的,但这一点不会以任何方式影响cmd.exe操作。
已在Windows XP和8.1上测试。这个管理在this site上有完整的描述。
https://stackoverflow.com/questions/45031925
复制相似问题