【问题标题】:Linux Text File Manipulation with sed/awk使用 sed/awk 处理 Linux 文本文件
【发布时间】:2010-01-20 15:51:09
【问题描述】:

我有一个如下格式的列表

77 Infinite Dust
4 Illusion Dust
12 Dream Shard
29 Star's Sorrow

我需要将其更改为:

77 <a href="http://www.wowhead.com/?search=Infinite Dust">Infinite Dust</a>
4 <a href="http://www.wowhead.com/?search=Illusion Dust">Illusion Dust</a>
12 <a href="http://www.wowhead.com/?search=Dream Shard">Dream Shard</a>
29 <a href="http://www.wowhead.com/?search=Star's Sorrow">Star's Sorrow</a>

我已经设法将这个列表变成了正确的格式,只是缺少了数字:

sed 's|^[0-9]*.|<a href="http://www.wowhead.com/?search=|g' filename | sed 's|$|">|g' | sed 's#<a[ \t][ \t]*href[ \t]*=[ \t]*".*search=\([^"]*\)">#&\1</a>#'

但我不知道如何让它保持列表前的数字,任何帮助表示赞赏,谢谢!

【问题讨论】:

  • 您在标签中提到了 sed 和 awk,但没有理由避免使用 perl。由于您也提到了 linux,因此您不太关心可移植性,并且几乎所有主要发行版(如果不是全部)都将包含 perl 解释器……那么为什么不使用它呢?
  • 我没有 perl 经验,但我相信它做得非常好!

标签: linux sed awk


【解决方案1】:

您可以使用 sed 将线条部分映射到组来执行此操作。在 sed 组中,(A)--(B) 中的 A 和 B 与 \1 和 \2 匹配,并增加了“()”需要转义的皱纹: 例如

sed 's/\([0-9]*\)\ \(.*\)$/\1 -- \2/g' testfile

将空间上的数字映射到第 1 组,并将后面的所有内容映射到第 2 组。然后,您可以将第 1 组和第 2 组映射到您喜欢的任何内容 - 例如通过将 sed 替换更改为类似

 \1 <a href.....\2">\2</a>

【讨论】:

    【解决方案2】:

    如果您在 last question 中告诉我们您最终想要做什么,我们会告诉您一个更简单的方法。

    正如我在my answer 中对您的最后一个问题所说,您可以让sed 记住模式的一部分,并将该部分称为\1\2 等。

    您需要分别记住数字和该行的其余部分,因此模式为:\([0-9]*\) \(.*\): 基本上是零个数字,后跟空格,然后是任意数量的字符。

    所以你的sed 命令变成:

    `sed -e 's|\([0-9]*\) \(.*\)|\1 <a href="http://www.wowhead.com/?search=\2">\2</a>|'
    

    该命令一次性完成您想要的所有操作。

    【讨论】:

    • 我实际上需要这两种解决方案,因为文件被分成两部分,一个包含开头的数字,另一个只包含项目名称。再次感谢您的帮助,非常感谢!
    【解决方案3】:
    awk '
    {
        s=""
        for(i=2;i<NF;i++) s=s$i
        s=s" "$NF
        printf $1 "<a href=\"http://www.wowhead.com/?search="s
        print "\042>"s"</a>"
    
    } ' file
    

    输出

    $ ./shell.sh
    77<a href="http://www.wowhead.com/?search=Infinite Dust">Infinite Dust</a>
    4<a href="http://www.wowhead.com/?search=Illusion Dust">Illusion Dust</a>
    12<a href="http://www.wowhead.com/?search=Dream Shard">Dream Shard</a>
    29<a href="http://www.wowhead.com/?search=Star's Sorrow">Star's Sorrow</a>
    

    【讨论】:

    • 数字后面只需要一个空格。
    【解决方案4】:

    在 sed 中,您可以使用 & 字符将匹配的模式放置在替换文本中。例如:

    回声 xyz | sed 's/^xyz/abc &/'

    会输出

    abc xyz

    所以在你的例子中,

    sed 's|^[0-9]*.|&

    【讨论】:

      【解决方案5】:

      使用 awk 会是这样的:

      {  
         rest = substr($0, length($1)+2, length($0));
         printf("%d <a href=\"http://www.wowhead.com/?search=%s\">%s</a>\n", $1, rest, rest); 
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-09
        • 2021-07-19
        • 1970-01-01
        • 1970-01-01
        • 2021-08-06
        • 2019-04-07
        • 1970-01-01
        • 2012-08-17
        相关资源
        最近更新 更多