如何获得非常不寻常的格式文本文件的必要值?

问题描述 投票:1回答:8

我有一个输出,这是一个像这样的文本文件(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
)

有人可以告诉我如何获得这个价值?

windows batch-file awk cmd
8个回答
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%

2
投票

既然你的问题被标记为,那怎么样

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())。


1
投票

你可以尝试一下(我没有在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环境中测试过这个


1
投票

试试这个批/ 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中,可以在以后使用。


1
投票

这个.bat文件脚本可能会为您提供所需的内容。

powershell -NoLogo -NoProfile -Command ^
    "Select-String -Path '.\test.txt' -Pattern '^\d+ .*\|\d+ .*\|\d+ .*\|(\d+).*$' |" ^
    "ForEach-Object { $_.Matches.Groups[1].Value }"

1
投票

这使您可以通过该值的名称访问输入文件中的所有数据:

$ 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

1
投票

查看提供的文件内容,您不需要复杂的搜索掩码:

@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)

1
投票

在批处理文件中,连续分隔符被计为我使用的分隔符

在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"
© www.soinside.com 2019 - 2024. All rights reserved.