使用多个命令创建 for 循环来读取 csv 文件时遇到问题

使用多个命令创建 for 循环来读取 csv 文件时遇到问题

我正在尝试创建一个 for 循环,该循环读取打印文件名、按字母顺序排列字段并添加 html 标签,最终创建一个如下所示的 html 文件

<h3 id= filename> file </h3>

<li> field2(field3)</li>
<li> field2(field3)</li>
<li> field2(field3)</li>...

<h3 id= filename> file </h3>

等等。

到目前为止我有这个:

     for file in *.csv; do
         awk 'FNR == 1{ print "<h3 id=" file ">" file "</h3>" }' | sort -t"," -k2 | awk -F "," '{print "<li>" $2 "(" $3 ")<\li>" }' > *.html 
     done

最后两个命令配合得很好,但第一个命令把它们搞乱了,我最终得到了一个空的 html 文件。我也不确定我是否为这种情况创建了正确的 for 循环。

答案1

您已经(为了可读性而稍微重新格式化):

for file in *.csv; do
  awk 'FNR == 1{ print "<h3 id=" file ">" file "</h3>" }' |
    sort -t"," -k2 |
    awk -F "," '{print "<li>" $2 "(" $3 ")<\li>" }' > *.html 
done
  1. 第一个awk命令没有任何意义。它既没有收到任何输入标准输入它也不接收文件列表作为参数:换句话说,它不处理任何内容。

    → 我们需要向 awk 提供输入,如下所示:

    awk '...awk script here...' "$file"
    

    或者通过将其输入标准输入

  2. 您正在尝试引用该awk变量file。但没有这样的变量。当然有一个变量具有该名称,但awk对此一无所知。

    → 我们需要将file变量提供给awk.我们可以做这样的事情:

    awk -v file="$file" ...
    
  3. 您尝试插入的方式sort 之间两次awk通话似乎很尴尬。

    → 我们sort先调用,然后将输出提供给awk

  4. 您永远不会<ul>...</ul>在列表元素周围创建。

    → 让我们确保将这些元素包含在我们的输出中。

  5. 您试图将输出重定向到*.html,但这不会达到您想要的效果。这将根据当前目录中存在的文件产生不同的行为。

    → 我们应该根据输入文件名构造输出文件名。如果something.csv我们想要输出一个名为 的输入文件something.html,我们可以这样写:

    "${file%.csv}.html"
    

    该表达式${file%.csv}是一个 bash 表达式,它.csv从变量的内容中删除file

看起来也许你想要类似的东西:

#!/bin/bash

for file in *.csv; do
  sort -t"," -k2 "$file" |
  awk -v file="$file" -F"," '
    BEGIN {
      printf "<h3 id=\"%s\">%s</h3>\n", file, file
      printf "<ul>\n"
    }
    {
        printf "<li>%s (%s)</li>\n", $2, $3
    }
    END {
      printf "</ul>\n"
    }
  ' > "${file%.csv}.html"
done

给定输入:

alice,8,alice,alice,alice
bob,6,bob,bob,bob
carol,7,carol,carol,carol
david,5,david,david,david
edith,4,edith,edith,edith
frank,3,frank,frank,frank
grace,2,grace,grace,grace

这会产生输出:

<h3 id="file1.csv">file1.csv</h3>
<ul>
<li>2 (grace)</li>
<li>3 (frank)</li>
<li>4 (edith)</li>
<li>5 (david)</li>
<li>6 (bob)</li>
<li>7 (carol)</li>
<li>8 (alice)</li>
</ul>

printf(您可以将我在 awk 脚本中使用的 替换为print,但我发现printf更容易使用。)

相关内容