我有一个输出,这是一个像这样的文本文件(C:\test.txt
)
database_name |database_size |unallocated space
--------------------------------------------------------------------------------------------------------------------------------|------------------|------------------
web | 11120.00 MB |11157.80 MB
(1 sˆ—‚³‚ê‚Ü‚µ‚½)
reserved |data |index_size |unused
------------------|------------------|------------------|------------------
111360 KB |11560 KB |11160 KB |111640 KB
(1 sˆ—‚³‚ê‚Ü‚µ‚½)
不用说,这是一团糟。但是,我想得到“未使用”列的值,即111640。
我的机器是Windows,我尝试了以下代码,但它没有给我任何东西:
@echo off
SET _c=
FOR /F "tokens=4 delims= " %%G IN (C:\test.txt) DO (
IF DEFINED _c <nul set /p z=", "
<nul set /p z=%%G
SET _c=1
)
有人可以告诉我如何获得这个价值?
另一个(更简单),只为收集!
@echo off
setlocal
for /F "tokens=3" %%a in ('"setx /F test.txt dummyVar /R 2,3 unused /D ^|"') do set "col=%%a" & goto continue
:continue
set "col=%col:~0,-1%"
echo %col%
所需的标记是搜索标记下方的两(2)行。所需令牌的行在搜索行中每个令牌有两个令牌。因此,令牌偏移量为3(而不是0)。
this site给出了这种方法的详细解释
编辑:添加了新方法
这个简单而标准的方法也有效,因为所需的值是文件中唯一的第七个标记!
@echo off
for /F "tokens=7 delims=| " %%a in (test.txt) do set "col=%%a"
echo %col%
既然你的问题被标记为awk,那怎么样
awk -F "|" "$NF ~ /unused/{p=1} p && /[0-9]/ { print $NF; p = 0 }" messyfile.txt
我希望双引号适用于Windows;在U * x上,我会在整个过程中使用单引号。
-F
设置字段分隔符,NF
是字段数;所以$NF
检查每一行的最后一个字段。如果我们在最后一个字段中看到unused
,请开始寻找一个数字。当我们看到包含至少一个数字的行时,打印该行的最后一个字段。
如果这足够接近你想要的,我相信你可以弄清楚如何调整它,例如删除KB
后缀(提示:sub()
或split()
)。
你可以尝试一下(我没有在Windows环境中测试过这个)。
awk '!flag{for(i=1;i<=NF;i++){if($i~/unused/){field=i;flag=1}}} flag && !/^-/{print $field,$(field+1);flag="";exit}' Input_file
如果您在Windows上,则需要将单引号更改为"
。
说明:这段代码的作用是查找找到字符串unused
的字段编号,然后查找下一行(没有-
)它将打印该特定及其下一个字段(其中包含kb
等信息)。我不是在这里为unused
字符串编码字段编号。
根据@MarkSetchell的评论,我们可以尝试创建一个code.awk
文件并像awk -f code.awk Input_file
一样运行,其中Input_file是示例文件。
code.awk
!flag{
for(i=1;i<=NF;i++){
if($i~/unused/){
field=i
flag=1
}
}
}
flag && !/^-/{
print $field,$(field+1)
flag=""
exit
}'
PS:公平警告我没有在Windows环境中测试过这个
试试这个批/ cmd版本:
@echo off
for /f "usebackq" %%i in (`for /f "tokens=4 delims=|" %%j in ^(C:\test.txt^) do @echo %%j`) do (
(echo %%i | findstr /R "[0-9][0-9]*" ) && set "thenum=%%i" && goto :outloop
)
:outloop
::echo %thenum%
::pause
该值也保存到变量thenum
中,可以在以后使用。
这个.bat文件脚本可能会为您提供所需的内容。
powershell -NoLogo -NoProfile -Command ^
"Select-String -Path '.\test.txt' -Pattern '^\d+ .*\|\d+ .*\|\d+ .*\|(\d+).*$' |" ^
"ForEach-Object { $_.Matches.Groups[1].Value }"
这使您可以通过该值的名称访问输入文件中的所有数据:
$ cat tst.awk
BEGIN { FS = "[[:space:]]*[|][[:space:]]*" }
{ gsub(/^[[:space:]]+|[[:space:]]+$/,"") }
prev1 ~ /^[-|]+$/ {
split(prev2,tags)
for (i=1; i<=NF; i++) {
tag = tags[i]
val = $i
tag2val[tag] = val
}
}
{ prev2 = prev1; prev1 = $0 }
END {
for (tag in tag2val) {
val = tag2val[tag]
printf "%s = <%s>\n", tag, val
}
print "---"
print tag2val["unused"]
}
$ awk -f tst.awk file
reserved = <111360 KB>
unallocated space = <11157.80 MB>
database_name = <web>
data = <11560 KB>
database_size = <11120.00 MB>
index_size = <11160 KB>
unused = <111640 KB>
---
111640 KB
如果您想要CSV输出,只需调整END部分:
$ cat tst.awk
BEGIN { FS = "[[:space:]]*[|][[:space:]]*" }
{ gsub(/^[[:space:]]+|[[:space:]]+$/,"") }
prev1 ~ /^[-|]+$/ {
split(prev2,tags)
for (i=1; i<=NF; i++) {
tag = tags[i]
val = $i
tag2val[tag] = val
}
}
{ prev2 = prev1; prev1 = $0 }
END {
sep = ""
for (tag in tag2val) {
printf "%s%s", sep, tag
sep = ","
}
print ""
sep = ""
for (tag in tag2val) {
printf "%s%s", sep, tag2val[tag]
sep = ","
}
print ""
}
$ awk -f tst.awk file
reserved,unallocated space,database_name,data,database_size,index_size,unused
111360 KB,11157.80 MB,web,11560 KB,11120.00 MB,11160 KB,111640 KB
查看提供的文件内容,您不需要复杂的搜索掩码:
@Echo Off
Set "UnUsed="
For /F "Tokens=4 Delims=|" %%A In ('Find " KB"^<"C:\test.txt" 2^>Nul'
) Do For %%B In (%%A) Do If Not Defined UnUsed Set "UnUsed=%%B"
If Defined UnUsed (Echo=%UnUsed% & Pause)
在批处理文件中,连续分隔符被计为我使用的分隔符
在cmd行
for /f "tokens=7 delims=| " %A in ('findstr "KB" C:\test.txt') do @set "unused_KB=%A"
在批处理文件中
@Echo off
for /f "tokens=7 delims=| " %%A in ('findstr "KB" C:\test.txt') do set "unused_KB=%%A"