在 while 循环中读取变量时 awk 中断

Awk breaks when reading variable in while-loop

我正在尝试从名为 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

它returns:

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

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

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

解释:

 awk '/file=/ { 
                lne=gensub(/(^.*=")(.*)(\".*$)/,"<a href=\"\2\">\2</a>",[=11=]);       # 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>",[=11=]);
                print lne
             } 
      /title=/ {                                                                      # Use the same logic for lines with title.
                lne=gensub(/(^.*=")(.*)(\".*$)/,"<h1>\2</h1>",[=11=]);
                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=\"\"></a>@;/date=/s@(^.*=")(.*)(\".*$)@<b></b>@;/title=/s@(^.*=")(.*)(\".*$)@<h1></h1>@' input/index.db

根据您展示的示例,请您尝试以下操作。这将生成一个正确的 HTML 文件,标题为 body 所有标签。

awk '
BEGIN{
  print "<html>"ORS"<title>Your title here..</title>"ORS"<body>"
}
!NF{ val="" }
match([=10=],/"[^"]*/){
  val=substr([=10=],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>

使用一些可重复使用的函数来包装 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","",), h("b","",), h("a",,)}' 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>