【问题标题】:Awk breaks when reading variable in while-loop在 while 循环中读取变量时,Awk 中断
【发布时间】:2021-05-22 14:21:15
【问题描述】:

我正在尝试从名为 index.db 的文本文件生成 html 文件。 index.db 的内容:

file="test.html"
    date="2013-01-07"
    title="Example title"

file="test2.html"
    date="2014-02-04"
    title="Second example title"

我正在尝试的命令:

sed '/^$/d;H;1h;$!d;g;s/\n\t\+/ /g' input/index.db |
    while read -r line; do
        awk '{
        print "<h1>"title"</h1>"
        print "<b>"date"</b>"
        print "<a href=\""file"\">"file"</a>"
    }' $line
done

然后它返回:

awk: fatal: cannot open file `title"' for reading: No such file or directory
awk: fatal: cannot open file `example' for reading: No such file or directory

但如果我尝试以下命令,它会完美运行:

sed '/^$/d;H;1h;$!d;g;s/\n\t\+/ /g' input/index.db |
    while read -r line; do
    echo $line
        awk '{
        print "<h1>"title"</h1>"
        print "<b>"date"</b>"
        print "<a href=\""file"\">"file"</a>"
    }' file="test.html" date="2013-01-07" title="Example title"
done

【问题讨论】:

  • echo $line 本身有问题,出于同样的原因,awk ... $line 也是。总是,总是引用你的扩展:echo "$line"awk ... "$line"——见I just assigned a variable, but echo $variable shows something else
  • ...也就是说,在循环中启动 awk 是一种“代码气味”——表明您做错了什么。 awk 最好只运行一次,然后让它自己循环。
  • @CharlesDuffy echo $line 只是为了查看命令是否运行了预期的次数。也就是说,评论 $line 不会给出错误,但仍然不会给出所需的输出。

标签: shell awk sh


【解决方案1】:

带有一些可重用的函数来包装html标签。

$ awk -F'[="]' -v RS= -v OFS='\n' -v ORS='\n\n' '
      function h(t,r,v) {return "<" t (r?" href=\"" r "\"":"")  ">"v "</"t">"}

      {print h("h1","",$9), h("b","",$6), h("a",$3,$3)}' file


<h1>Example title</h1>
<b>2013-01-07</b>
<a href="test.html">test.html</a>

<h1>Second example title</h1>
<b>2014-02-04</b>
<a href="test2.html">test2.html</a>

【讨论】:

    【解决方案2】:

    Awk 旨在处理文件,因此您不需要在循环中逐行处理。此外,awk 和 sed 通常可以互换,但很少一起使用。您可以使用“完整”的 awk 解决方案来做您需要做的事情。使用 GNU awk:

    awk '/file=/ { lne=gensub(/(^.*=")(.*)(\".*$)/,"<a href=\"\\2\">\\2</a>",$0);print lne} /date=/ {lne=gensub(/(^.*=")(.*)(\".*$)/,"<b>\\2</b>",$0);print lne} /title=/ {lne=gensub(/(^.*=")(.*)(\".*$)/,"<h1>\\2</h1>",$0);print lne}' input/index.db
    

    解释:

     awk '/file=/ { 
                    lne=gensub(/(^.*=")(.*)(\".*$)/,"<a href=\"\\2\">\\2</a>",$0);       # Use the gensub function to split any lines with "file", into three section, leaving the section between quotes in section 2. We then surround section 2 with the required htlm and read the result in to the variable lne.
                    print lne                                                            # Print lne
                  } 
          /date=/ {                                                                       # Use the same logic for lines with date.
                    lne=gensub(/(^.*=")(.*)(\".*$)/,"<b>\\2</b>",$0);
                    print lne
                 } 
          /title=/ {                                                                      # Use the same logic for lines with title.
                    lne=gensub(/(^.*=")(.*)(\".*$)/,"<h1>\\2</h1>",$0);
                    print lne
                  }' input/index.db
    

    输出:

    <a href="test.html">test.html</a>
    <b>2013-01-07</b>
    <h1>Example title</h1>
    <a href="test2.html">test2.html</a>
    <b>2014-02-04</b>
    <h1>Second example title</h1
    

    这种方法也可以与 sed 以非常相似的方式使用:

    sed -r '/file=/s@(^.*=")(.*)(\".*$)@<a href=\"\2\">\2</a>@;/date=/s@(^.*=")(.*)(\".*$)@<b>\2</b>@;/title=/s@(^.*=")(.*)(\".*$)@<h1>\2</h1>@' input/index.db
    

    【讨论】:

      【解决方案3】:

      对于您显示的示例,您能否尝试以下操作。这将生成一个正确的 HTML 文件,其中包含标题、正文所有标签。

      awk '
      BEGIN{
        print "<html>"ORS"<title>Your title here..</title>"ORS"<body>"
      }
      !NF{ val="" }
      match($0,/"[^"]*/){
        val=substr($0,RSTART+1,RLENGTH-1)
      }
      /^file=/{
        print "<a href=\"" val "\"</a>"
        next
      }
      /date=/{
        print "<b>" val "</b>"
        next
      }
      /title/{
        print "<h1>"val"</h1>"
      }
      END{
        print "</body>" ORS "</html>"
      }
      '  Input_file
      

      上面将生成以下html文件(根据示例的详细信息):

      <html>
      <title>Your title here..</title>
      <body>
      <a href="test.html"</a>
      <b>2013-01-07</b>
      <h1>Example title</h1>
      <a href="test2.html"</a>
      <b>2014-02-04</b>
      <h1>Second example title</h1>
      </body>
      </html>
      

      【讨论】:

        猜你喜欢
        • 2012-10-18
        • 2010-12-04
        • 1970-01-01
        • 2014-11-13
        • 2013-06-26
        • 2018-04-17
        • 1970-01-01
        • 2019-03-23
        • 1970-01-01
        相关资源
        最近更新 更多