• bat中for /f 如何截取任意行


    一、概述

    for命令开关有很多,/L,/F,/R。这里仅对含有/F的for进行分析,这个可能是最常用的,也是最强的命令,主要用来处理文件和一些命令的输出结果。

    1.命令格式:
    (1).FOR /F ["options"] %%i IN (file) DO command
    (2).FOR /F ["options"] %%i IN ("string") DO command--注意双引号
    (3).FOR /F ["options"] %%i IN ('command') DO command--注意单引号

    2.参数说明:

    file代表一个或多个文件,可以使用通配符。
    string 代表字符串
    command代表命令
    ["options"]选项有多个:

     eol=c           - 指定一个行注释字符,遇到c开头的行就忽略掉。
     skip=n          - 指定在文件开始时忽略的行数。
     delims=xxx      - 指定分隔符。默认是空格和TAB。

     tokens=x,y,m-n  - 指每行的哪一个符号被传递到每个迭代
                       的 for 本身。这会导致额外变量名称的分配。m-n
                       格式为一个范围。通过 nth 符号指定 mth。如果
                       符号字符串中的最后一个字符星号,
                       那么额外的变量将在最后一个符号解析之后
                       分配并接受行的保留文本。
     usebackq        - 1.把单引号字符串作为命令;2.允许中使用双引号扩起文件名称。

    二、详细介绍
    1.FOR /F %%i IN (file) DO command
        file为文件名,按照官方的说法是,for会依次将file中的文件打开,并且在进行到下一个文件之前将每个文件读取到内存,按照每一行为一个元素,忽略空白的行。
        假如文件d:out.txt中有如下内容:

      第1行第1列第1行第2列第1行第3列
      第2行第1列第2行第2列第2行第3列
      第3行第1列第3行第2列第3行第3列

    怎么遍历文件中的内容呢?下面的语句可以:
    for /f %%i in (d:out.txt) do echo %%i


    执行过程:for会先打开out.txt,然后读出out.txt里面的所有内容,把它作为一个集合,并且以每一行(文件中无分隔符情况下)作为一个元素,用%%i依次代替每个元素,然后执行do后面的命令。


    for /f会默认以每一行(无分隔符)来作为一个元素,但是有分隔符怎么办?假如out.txt内容变成如下:

      第1行第1列 第1行第2列 第1行第3列
      第2行第1列 第2行第2列 第2行第3列
      第3行第1列 第3行第2列 第3行第3列

    那么for /f %%i in (d:out.txt) do echo %%i就无法将所有的内容显示出来。显示结果如下:

      第1行第1列
      第2行第1列
      第3行第1列

    因为命令默认是以空格和TAB为分隔符,所以它遇到分割符之后,默认只取第一个,就将分割符后面的都丢掉了。

    如果我们还想把每一行再分解更小的内容,该怎么办呢?for命令提供了更多的参数,它们就是:delims和tokens
    delims :告诉for每一行应该拿什么作为分隔符,默认的分隔符是空格和tab键
    比如,我们执行下面的命令:

    for /f "delims= " %%i in (d:out.txt) do echo %%i

    显示的结果:

    第1行第1列
    第2行第1列
    第3行第1列

    这个命令和for /f %%i in (d:out.txt) do echo %%i的效果是一样的。

    如果我们想要每一行的后面的元素,那又如何呢?这个时候就可以利用tokens参数,它的作用就是当你通过delims将每一行分为更小的元素时,由tokens来控制要取哪一个或哪几个。
    还是上面的例子,执行如下命令:

    for /f "tokens=2 delims= " %%i in (d:out.txt) do echo %%i

    执行结果:

    第1行第2列
    第2行第2列
    第3行第2列

    如果要显示第二列和第三列,则换成tokens=2,3或tokens=2-3,全部显示则使用通配符tokens=*。


    注意:如果显示多个元素(非*),比如这里的tokens=2-3,语句应该写成这样:

    for /f "tokens=2,3 delims= " %%i in (d:out.txt) do echo %%i %%j

    怎么多出一个%%j?
    这是因为你的tokens后面要取每一行的两列,用%%i来替换第二列,用%%j来替换第三列。
    并且必须是按照英文字母顺序排列的,%%j不能换成%%k,因为i后面是j。
    执行结果为:

    第1行第2列 第1行第3列
    第2行第2列 第2行第3列
    第3行第2列 第3行第3列

    又如下面语句:

    for /f "tokens=2,* delims= " %%i in (d:out.txt) do echo %%i %%j
    它显示从第二列到最后的一列,执行结果为:

    第1行第2列 第1行第3列
    第2行第2列 第2行第3列
    第3行第2列 第3行第3列

    用%%i代替第二列,用%%j代替剩余的所有。


    最后还有skip,eol和usebackq。

    skip就是要忽略文件的前多少行,eol用来指定当一行以什么符号开始时,就忽略它。比如:

    for /f "skip=2 tokens=*" %%i in (d:out.txt) do echo %%i
    结果为:

    第3行第1列 第3行第2列 第3行第3列

    用skip来告诉for跳过前两行。

    再如,当out.txt内容变成:

    #第1行第1列 第1行第2列 第1行第3列
    #第2行第1列 第2行第2列 第2行第3列
    第3行第1列 第3行第2列 第3行第3列

    for /f "eol=# tokens=*" %%i in (d:out.txt) do echo %%i

    结果是:

    第3行第1列 第3行第2列 第3行第3列

    用eol来告诉for忽略以“.”开头的行。

    usebackq就是反转的意思,他把字符串("out.txt")当做文件,或者把命令('command')当做字符串。

    例如:

    for /f "usebackq eol=# tokens=*" %%i in ("d:out.txt") do echo %%i

    结果是:

    第3行第1列 第3行第2列 第3行第3列

    如果不加usebackq,则"d:out.txt"会被当成字符串。

    又例如:

    for /f "usebackq tokens=*" %%i in ('echo helloworld!') do echo %%i

    结果:

    echo helloworld!

    ,这里命令被当成了字符串。

    如果没有usebackq

    for /f "tokens=*" %%i in ('echo helloworld!') do echo %%i

    结果:

    helloworld!

    2.FOR /F ["options"] %%i IN ("string") DO command

    例子:

    for /f "tokens=2,* delims= " %%i in ("this is an example!") do echo %%i %%j

    结果:

    is an example!

    对于字符串的处理类似于文件的处理,此处不再赘述。

    3.FOR /F ["options"] %%i IN ('command') DO command

     该命令将command的执行结果作为集合,后面的处理类似文件处理,此处不再赘述。


    方法1. 用find命令查找指定字符串

    @Echo Off
    For /f "delims=" %%i in ('Type 1.txt^|Find "疑似"') do (Echo %%i)
    Pause

    追问:
    如果我根本不知道1.txt内容,只知道共四行,想单独显示第二行,该怎么写?
    追答:
    @Echo Off&Setlocal Enabledelayedexpansion
    For /f "delims=" %%i in (1.txt) do (
    Set /a n+=1 
    If !n!==2 Echo %%i
    )
    Pause

    只显示第二行

    追问:
    本人较为愚钝,没看懂,但能实现,谢谢。若能写个分别将1.txt中的2 4 6行内容分别赋给变量a b c 就再追加20分。谢谢
    追答:
    For /f "delims=" %%i in (1.txt) do (
    Set /a n+=1 
    If !n!==2 Set a=%%i
    If !n!==4 Set b=%%i
    If !n!==6 Set c=%%i
    )
    Echo %a% %b% %c%
    Pause
    

      

  • 相关阅读:
    POJ 3041 Asteroids 二分图匹配
    ZOJ 3705 Applications 模拟
    UNIX环境高级编程(第3版)
    明清美文四卷本(共四册)
    卑鄙的圣人:曹操(全10册)
    爱丽丝梦游仙境
    我在大清官场30年
    乌合之众:大众心理研究
    Java多线程编程实战指南
    Linux就该这么学
  • 原文地址:https://www.cnblogs.com/ranson7zop/p/7544887.html
Copyright © 2020-2023  润新知