根据 AWK 脚本的模式处理文本的特定部分

根据 AWK 脚本的模式处理文本的特定部分

我正在 awk 中开发一个脚本,根据我的喜好将 tex 文档转换为 html。

#!/bin/awk -f

BEGIN {
    FS="\n";
    print "<html><body>"
}
# Function to print a row with one argument to handle either a 'th' tag or 'td' tag
function printRow(tag) {
    for(i=1; i<=NF; i++) print "<"tag">"$i"</"tag">";
}

NR>1 {
   [conditions]
   printRow("p")
}

END {
    print "</body></html>"
}

正如所见,它处于非常年轻的发展阶段。

\documentclass[a4paper, 11pt, titlepage]{article}
\usepackage{fancyhdr}
\usepackage{graphicx}
\usepackage{imakeidx}
[...]

\begin{document}

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla placerat lectus sit amet augue facilisis, eget viverra sem pellentesque. Nulla vehicula metus risus, vel condimentum nunc dignissim eget. Vivamus quis sagittis tellus, eget ullamcorper libero. Nulla vitae fringilla nunc. Vivamus id suscipit mi. Phasellus porta lacinia dolor, at congue eros rhoncus vitae. Donec vel condimentum sapien. Curabitur est massa, finibus vel iaculis id, dignissim nec nisl. Sed non justo orci. Morbi quis orci efficitur sem porttitor pulvinar. Duis consectetur rhoncus posuere. Duis cursus neque semper lectus fermentum rhoncus.

\end{document}

我想要的是,脚本仅解释\begin{document}和之间的行\end{document},因为在它们导入库、变量等之前;目前我对此不感兴趣。

我如何才能使它只处理该模式内的文本?

答案1

不要使用 shebang 调用 awk,它只会使事情变得更加复杂,并剥夺您利用 shell 功能和 awk 功能的能力,并将脚本与 awk 特定的语法紧密耦合,请参阅https://stackoverflow.com/a/61002754/1745001

以下是开始编写脚本的方法:

#!/usr/bin/env bash

awk '

    BEGIN {
        print "<html><body>"
    }
    
    # Function to print a row with one argument to handle either a "p" or "th" tag or "td" tag
    function printRow(tag,    i) {
        for(i=1; i<=NF; i++) print "<"tag">" $i "</"tag">"
    }
    
    $0 == "\begin{document}" { f=1 }
    $0 == "\end{document}"   { f=0 }
    
    !f { next }
    
    [conditions] {
       printRow("p")      # or "th" or "td"
    }
    
    END {
        print "</body></html>"
    }

' "${@:--}"

我删除了,FS="\n"因为您在函数中使用了从 1 到 NF 的循环,如果 FS 和 RS 是同一件事,那就没有意义,因为这会导致 NF 始终为 1。

答案2

我认为这应该很容易实现:您可以例如指定一个0BEGIN块中初始化的标志(这是可选的,因为awk在布尔测试中将未初始化的变量评估为“false”)。您将指示awk专门检查该行是否声明\begin{document}该标志是否未设置,否则忽略该行。只有遇到该语句时才\begin将标志设置为1,然后执行通常的处理。如果\end{document}遇到,则该标志将被重置。

因此,您可以按如下方式修改脚本:

!f{if ($1=="\begin{document}") f=1; next}

f && ($1=="\end{document}") {f=0; next}

f==1 {
   [conditions]
   printRow("p")
}

这里的“set”和“reset”条件是不同的,因为 whilef未设置,你想跳过每一个线(包括\begin{document})行,但是此外\begin如果找到该语句则设置标志,而如果f,而如果设置了该标志,则需要重置它仅当当前行为 时才跳过该行\end{document}

相关内容