Linux 如何从文本文件中为grep信息编写sed脚本

Linux 如何从文本文件中为grep信息编写sed脚本,linux,sed,append,newline,Linux,Sed,Append,Newline,我正在尝试做我的家庭作业,仅限于使用sed将输入文件过滤为特定格式的输出。这是输入文件(名为stocks): 输出需要是: BAC, CSCO, INTC, MSFT, VZ, KO, MMM 我确实想出了一个解决办法,但效率不高。这是我的sed脚本(名为try.sed): 我在shell上运行的命令是: $ sed -nf try.sed stocks 我的问题是,有没有更好的方法使用sed来获得相同的结果?我编写的脚本只能处理7行数据。如果数据较长,我需要重新修改脚本。我不知道怎样才能让

我正在尝试做我的家庭作业,仅限于使用
sed
将输入文件过滤为特定格式的输出。这是输入文件(名为
stocks
):

输出需要是:

BAC, CSCO, INTC, MSFT, VZ, KO, MMM
我确实想出了一个解决办法,但效率不高。这是我的
sed
脚本(名为
try.sed
):

我在shell上运行的命令是:

$ sed -nf try.sed stocks
我的问题是,有没有更好的方法使用sed来获得相同的结果?我编写的脚本只能处理7行数据。如果数据较长,我需要重新修改脚本。我不知道怎样才能让它变得更好,所以我来这里寻求帮助


感谢您的建议。

此sed命令应生成您所需的输出:

sed -rn '/[0-9]+$/{s/^([^;]*).*$/\1/p;}' file.txt
或在Mac上:

sed -En '/[0-9]+$/{s/^([^;]*).*$/\1/p;}' file.txt

<> > >编辑:我编辑了我的算法,因为我忽略了页眉和页脚(我认为它们只是为了我们的利益)。 sed根据其设计,访问输入文件的每一行,然后对符合某些规范(或无)的行执行表达式。如果你把你的脚本裁剪成一定数量的行,你肯定是做错了什么!我不会给你写剧本,因为这是家庭作业,但一种方法的总体思路是写一个剧本,完成以下任务。将排序视为脚本中事物的顺序

  • 使用
    d
    跳过前三行,这将删除图案空间并立即移动到下一行
  • 对于不是空行的每一行,请执行以下步骤。(这将全部放在一组花括号中。)
  • 使用
    s
    (substitute)命令将第一个分号(
    )后面的所有内容替换为逗号和空格(“,”)
  • 将当前模式空间追加到(查看
    H
  • 删除模式空间并继续下一行,如步骤1所示
  • 对于脚本中到达这一点的每一行(应该是第一个空行),将保留空间的内容检索到模式空间中。(这将在上面的花括号之后。)
  • 将模式空间中的所有新行替换为空
  • 接下来,用零替换模式空间中的最后一个逗号和空格
  • 最后,退出程序,这样就不会再处理任何行。我的脚本在没有这个的情况下工作了,但我不能100%确定为什么
  • 话虽如此,这只是解决问题的一种方法
    sed
    通常提供不同复杂度的不同方法来完成任务。我用这种方法编写的解决方案有10行长

    请注意,我不需要抑制打印(使用
    -n
    )或手动打印(使用
    p
    );默认情况下打印每一行。我的脚本如下所示:

    $ sed -f companies.sed companies 
    BAC, CSCO, INTC, MSFT, VZ, KO, MMM
    

    使用
    sed
    的另一种方法:

    /.*;.*;[0-9].*/ { N
    N
    N
    N
    N
    N
    s/\(.*\);.*;.*\n\(.*\);.*;.*\n\(.*\);.*;.*\n\(.*\);.*;.*\n\(.*\);.*;.*\n\(.*\);.*;.*\n\(.*\);.*;.*/\1, \2, \3, \4, \5, \6, \7/gp
    }
    
    sed -ne '/^====/,/^====/ { /;/ { s/;.*$// ; H } }; $ { g ; s/\n// ; s/\n/, /g ; p }' stocks
    
    输出:

    BAC, CSCO, INTC, MSFT, VZ, KO, MMM
    
    说明:

    -ne               # Process each input line without printing and execute next commands...
    /^====/,/^====/   # For all lines between these...
    {
      /;/             # If line has a semicolon...
      { 
        s/;.*$//      # Remove characters from first semicolon until end of line.
        H             # Append content to 'hold space'.
      }
    };
    $                 # In last input line...
    {
      g               # Copy content of 'hold space' to 'pattern space' to work with it.
      s/\n//          # Remove first newline character.
      s/\n/, /g       # substitute the rest with output separator, comma in this case.
      p               # Print to output.
    

    这可能适合您:

    sed '1d;/;/{s/;.*//;H};${g;s/.//;s/\n/, /g;q};d' stocks
    
    • 我们不需要标题,所以让我们删除它们<代码>1d
    • 所有数据项由
      分隔,让我们把注意力集中在这些行上<代码>//
    • 以上内容中,删除第一个
      中的所有内容到行的末尾,然后将其塞进保留空间(HS)
      {s/;*/;H}
    • 当到达最后一行时,使用
      g
      命令用HS覆盖它,删除第一个换行符(由
      H
      命令生成),用逗号和空格替换所有后续换行符,并打印出剩余的换行符<代码>${g;s/;s/\n/,/g;q}
    • 删除所有其他内容
      d
    下面是一个终端会话,显示了构建sed命令的增量优化:

    cat <<! >stock # paste the file into a here doc and pass it on to a file
    > Symbol;Name;Volume
    > ================================================
    > 
    > BAC;Bank of America Corporation Com;238,059,612
    > CSCO;Cisco Systems, Inc.;28,159,455
    > INTC;Intel Corporation;22,501,784
    > MSFT;Microsoft Corporation;23,363,118
    > VZ;Verizon Communications Inc. Com;5,744,385
    > KO;Coca-Cola Company (The) Common;3,752,569
    > MMM;3M Company Common Stock;1,660,453
    > 
    > ================================================
    > !
    sed '1d;/;/!d' stock # delete headings and everything but data lines
    BAC;Bank of America Corporation Com;238,059,612
    CSCO;Cisco Systems, Inc.;28,159,455
    INTC;Intel Corporation;22,501,784
    MSFT;Microsoft Corporation;23,363,118
    VZ;Verizon Communications Inc. Com;5,744,385
    KO;Coca-Cola Company (The) Common;3,752,569
    MMM;3M Company Common Stock;1,660,453
    sed '1d;/;/{s/;.*//p};d' stock # delete all non essential data
    BAC
    CSCO
    INTC
    MSFT
    VZ
    KO
    MMM
    sed '1d;/;/{s/;.*//;H};${g;l};d' stock # use the l command to see what's really there!
    \nBAC\nCSCO\nINTC\nMSFT\nVZ\nKO\nMMM$
    sed '1d;/;/{s/;.*//;H};${g;s/.//;s/\n/, /g;l};d' stock # refine refine
    BAC, CSCO, INTC, MSFT, VZ, KO, MMM$
    sed '1d;/;/{s/;.*//;H};${g;s/.//;s/\n/, /g;q};d' stock # all done!
    BAC, CSCO, INTC, MSFT, VZ, KO, MMM
    
    cat符号;名称卷
    > ================================================
    > 
    >美国银行;美国银行股份有限公司;238,059,612
    >CSCO;思科系统公司。;28,159,455
    >INTC;英特尔公司;22,501,784
    >MSFT;微软公司;23,363,118
    >VZ;威瑞森通讯公司,;5,744,385
    >高,;可口可乐公司(通用);3,752,569
    >嗯,;3M公司普通股;1,660,453
    > 
    > ================================================
    > !
    sed'1d;/;/!d'stock#删除标题和除数据行以外的所有内容
    美国银行;美国银行股份有限公司;238,059,612
    CSCO;思科系统公司。;28,159,455
    INTC;英特尔公司;22,501,784
    MSFT;微软公司;23,363,118
    VZ;威瑞森通讯公司,;5,744,385
    让开;可口可乐公司(通用);3,752,569
    嗯,;3M公司普通股;1,660,453
    sed'1d;//{s/;*//p};d'库存#删除所有非必要数据
    美国银行
    CSCO
    INTC
    MSFT
    VZ
    击倒对手
    嗯
    sed'1d;//{s/;*/;H}${g;l};d'stock#使用l命令查看实际情况!
    \nBAC\nCSCO\nINTC\nMSFT\nVZ\nKO\nMMM$
    sed'1d;//{s/;*/;H}${g;s//;s/\n/,/g;l};d’库存#精炼
    BAC、CSCO、INTC、MSFT、VZ、KO、MMM$
    sed'1d;//{s/;*/;H}${g;s//;s/\n/,/g;q};d’stock,全部完成!
    BAC、CSCO、INTC、MSFT、VZ、KO、MMM
    
    亲爱的anubhava,我已经运行了您的命令,但输出不在一行中。挑战之一是将所有换行符替换为逗号和1个空格(最后一行除外)。最后一个后面不应该有逗号。是的,我的脚本的行为与grep-o完全一样,因为现在我意识到这是一个家庭作业,我将把脚本的其余部分留给你。@Jayce关于你答案的另一个提示是使用标签(如@Dan在他的答案中所建议的),使用
    N
    并用
    替换
    换行符
    空间
    谢谢Jaypal和Anubhava。。。我试图阅读更多关于b和t命令标签的内容。虽然,我还不太明白t在做什么……+1承认这是家庭作业,并承认这是疯狂的
    s/\(.*)/你放进去的东西!祝你好运。@Jayce上面哪一部分你有问题?如果可以的话,我想改进我的解释!嗨,丹,谢谢你的提示。1秒
    
    cat <<! >stock # paste the file into a here doc and pass it on to a file
    > Symbol;Name;Volume
    > ================================================
    > 
    > BAC;Bank of America Corporation Com;238,059,612
    > CSCO;Cisco Systems, Inc.;28,159,455
    > INTC;Intel Corporation;22,501,784
    > MSFT;Microsoft Corporation;23,363,118
    > VZ;Verizon Communications Inc. Com;5,744,385
    > KO;Coca-Cola Company (The) Common;3,752,569
    > MMM;3M Company Common Stock;1,660,453
    > 
    > ================================================
    > !
    sed '1d;/;/!d' stock # delete headings and everything but data lines
    BAC;Bank of America Corporation Com;238,059,612
    CSCO;Cisco Systems, Inc.;28,159,455
    INTC;Intel Corporation;22,501,784
    MSFT;Microsoft Corporation;23,363,118
    VZ;Verizon Communications Inc. Com;5,744,385
    KO;Coca-Cola Company (The) Common;3,752,569
    MMM;3M Company Common Stock;1,660,453
    sed '1d;/;/{s/;.*//p};d' stock # delete all non essential data
    BAC
    CSCO
    INTC
    MSFT
    VZ
    KO
    MMM
    sed '1d;/;/{s/;.*//;H};${g;l};d' stock # use the l command to see what's really there!
    \nBAC\nCSCO\nINTC\nMSFT\nVZ\nKO\nMMM$
    sed '1d;/;/{s/;.*//;H};${g;s/.//;s/\n/, /g;l};d' stock # refine refine
    BAC, CSCO, INTC, MSFT, VZ, KO, MMM$
    sed '1d;/;/{s/;.*//;H};${g;s/.//;s/\n/, /g;q};d' stock # all done!
    BAC, CSCO, INTC, MSFT, VZ, KO, MMM