【问题标题】:tokens and delims help extracting different columns of data from text标记和分隔符有助于从文本中提取不同的数据列
【发布时间】:2016-12-04 12:48:03
【问题描述】:

如果可以的话,请提供一个快速提示。我正在使用tokensdelims(批处理)进行一些测试,并且有一些很棒的代码,一些好心人为我准备了一些代码。

这是代码:

for /F "usebackq delims=" %%a in ("hosts.txt") do (
   for %%b in (%%a) do (
      set "hostname=!version!"
      set "version=!last!"
      set "last=%%b"    
    )
    echo !hostname! !version!>>"hosts2.txt"
)

它熟练地从带有内容的文本文件中提取

2 Dec 2016 14:37 GMT    194.176.105.139 United Kingdom  ID006972.CENTRAL    3.10.6.0    Remove
2 Dec 2016 14:34 GMT    194.176.105.132 United Kingdom  ID007574.CENTRAL    3.10.6.0    Remove

数据(如下)...(供我使用)。

但是,我有兴趣知道它是如何做到的?

以及如何更改它以添加 IP 地址列。

公式是什么?

它在隐藏的元变量中吗?

ID006972.CENTRAL    3.10.6.0    
ID007574.CENTRAL    3.10.6.0    

如何更改它以将其提取为如下所示:

194.176.105.132  ID007574.CENTRAL    3.10.6.0
194.176.105.139  ID006972.CENTRAL    3.10.6.0

甚至出于学习目的,例如使用日期列而不是 IP。

2 Dec 2016 14:37 GMT  ID007574.CENTRAL    3.10.6.0
2 Dec 2016 14:34 GMT  ID006972.CENTRAL    3.10.6.0

谢谢

【问题讨论】:

    标签: batch-file token


    【解决方案1】:

    您可以通过插入四个echo 命令来查看发生了什么,并从命令提示符窗口中运行批处理文件,当前目录是批处理文件的目录。

    @echo off
    setlocal EnableDelayedExpansion
    del "hosts2.txt" 2>nul
    for /F "usebackq delims=" %%a in ("hosts.txt") do (
        echo/
        echo Loop variable a is: %%a
        echo/
        for %%b in (%%a) do (
            echo Loop variable b is: %%b
            set "hostname=!version!"
            set "version=!last!"
            set "last=%%b"
        )
        echo !hostname! !version!>>"hosts2.txt"
    )
    endlocal
    pause
    

    外部 FOR 只是从hosts.txt 中读取一整行,并将该行分配给循环变量a

    内部 FOR 处理这一行。命令 FOR 没有任何附加选项,例如 /F,使用空格、制表符、逗号和其他一些字符作为处理圆括号内的字符串(集合)的分隔符。

    分配给loop变量b的当前字符串被分配给环境变量last。但在将 environment 变量 version 的当前值分配给 environment 变量 hostnamelastversion 之前,会产生旋转字符串分配。

    这样做是因为来自hosts.txt 中最后一个和最后一个数据列的数据与一个大问题有关,即文本文件中空格/制表符分隔的字符串的数量因国家/地区而异名称还可以包含一个空格字符,例如 United Kingdom

    可以轻松修改批处理代码以获取额外的 IP 地址并额外优化内部 FOR 循环以减少循环运行次数。

    @echo off
    setlocal EnableDelayedExpansion
    del "hosts2.txt" 2>nul
    for /F "usebackq tokens=6,7*" %%a in ("hosts.txt") do (
        echo/
        echo Loop variable a is: %%a
        echo Loop variable b is: %%b
        echo Loop variable c is: %%c
        echo/
        for %%d in (%%c) do (
            echo Loop variable d is: %%d
            set "hostname=!version!"
            set "version=!last!"
            set "last=%%b"
        )
        echo %%a !hostname! !version!>>"hosts2.txt"
    )
    endlocal
    pause
    

    外部 FOR 循环现在也从文本文件中读取整行,但使用空格/制表符作为分隔符将其拆分为单独的字符串(标记)。

    前 5 个空格/制表符分隔的字符串是:

    2 Dec 2016 14:37 GMT
    

    这 5 个字符串不感兴趣。

    有趣的是第六个空格/制表符分隔的字符串,它是 IP 地址。由于tokens=6,这第六个标记被分配给第一个循环变量a

    第七个空格分隔的字符串是国家名称的(第一部分),它是根据ASCII table 分配给下一个循环变量的标记7,即循环 变量b。现在应该清楚为什么循环变量区分大小写而环境变量不区分大小写。将多个标记分配给多个循环变量需要循环变量区分大小写。

    标记 7 之后的空格/制表符之后的所有内容都分配给 循环 变量 c,因为 7 之后的 tokens= 中的 * 没有进一步拆分。因此,分配给c 的字符串要么以国家/地区的其余部分开头,要么以 ID 字符串开头,并包含该行的其余部分。

    该行的剩余部分国家部分数量未知,由内部 FOR 循环处理,如上所述。

    要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

    • del /?
    • echo /?
    • endlocal /?
    • for /?
    • set /?
    • setlocal /?

    有关>>2>nul 的解释,另请参阅Microsoft 文章Using command redirection operators

    【讨论】:

    • 我喜欢这个解释! +1 我只建议不要使用echo. 留下空白行,而是使用echo/。前者速度较慢,因为系统搜索%PATH% 寻找一个名为echo 的可执行文件,带有通常的扩展名。如果偶然发现这样的文件,这种行为也可能会导致令人不快的意外。见this post
    • @Aacini 感谢有关echo. 的提示和帖子的链接。我不知道这个问题。我以后只会使用echo/ 来打印一个空行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    • 2019-08-06
    • 1970-01-01
    • 2016-05-06
    相关资源
    最近更新 更多