Как мне заставить этот скрипт bash создать HTML-файл, используя входные данные из файла template.vars?

0

Мне нужно, чтобы этот скрипт создавал, а затем выводил данные html файла внутри template.vars. Сценарий - это механизм шаблонов, но сейчас все, что он делает, - это ввести ввод с клавиатуры, повторив имя в шаблоне.vars, когда вход будет @NAME @. Вот код механизма шаблона на данный момент:

#!/bin/bash
IFS=@  #makes @ a delimiter. 
while read line
do
  dataspace=$(awk '$0=$1' FS== <<< "$line")
    value=$(awk '$0=$2' FS== <<< "$line")
  printf -v $dataspace "$value"                     #make the value stored in value into the name of a dataspace.
done < 'template.vars' #read template.vars for standard input.
skipflag=false           #initialize the skipflag to false                       
while read line                                 #while it is reading standard input one line at a time
do
  read -a dataspacearray <<< "$line"                #make the line into an array.
  if [ $skipflag == false ] && [ "${dataspacearray[1]}" != "ENDIF" ] ; then
        if [[ ${dataspacearray[1]} == "IF "* ]] ; then #If second element of dataspacearray is "IF "(something)
          dataspace='echo ${dataspacearray[1]} | cut -d' ' -f2'
          if [ -z "${!dataspace}" ] ; then                #if dataspace not found, skip everything up to endif. -z to test string
            skipflag=true
            fi
        else
          for ((i=0; i<${#dataspacearray[@]}; i++))
          do
            dataspace=${dataspacearray[i]}                    #access to each dataspace in the array
            even='expr $i % 2'  
                    if [ $even == '0' ] ; then                #if it even(f0,f2, f4.. etc. etc) then it not a variable, so print it directly
              if [ -n "${dataspace}" ] ; then
                printf ${dataspace}
              fi
            else                                      #(odd dataspaces(f1, f3... etc.) are variables, print their values if they exist
              if [ -n "${!dataspace}" ] ; then
                printf ${!dataspace}
              else
                printf "Error!!!"
              fi
            fi
          done
          printf "\n"
        fi
  else     
    skipflag=false
  fi
done

Файл html входит в качестве входного файла следующим образом:

<html>
  <head>
    <title>@NAME@</title>
  </head>
  <body>
    <p>Name: @NAME@</p>
    <p>Major: @MAJOR@</p>
    <p>Classification: @CLASS@</p>
    <p>Graduation date: @GDATE@</p>
@IF HONORS@
    <p>Graduating with Honors</p>
@ENDIF@
  </body>
</html>

С помощью скрипта, заменяющего все строки, начинающиеся и заканчивающиеся на @, используя данные в файле template.vars (или вывод ошибки !!!, если это не найдено). Я видел много примеров, когда шаблоны заменяют любой текст, который имеет значение $ в начале, и думаю, что мне нужно реализовать что-то подобное, но с ним чтение html файла в качестве ввода, а затем сохранение его в качестве вывода. Как мне это сделать?

Теги:
templates
template-engine

1 ответ

1
Лучший ответ

Это не строго то, о чем вы просили, но это, вероятно, достаточно близко, чтобы дать вам что-то для работы.

Оставляя в стороне @IF... @... @ENDIF @обработку (которая в основном непроверенная запоздалая мысль), логика выглядит примерно так:

Для каждой входной линии

1) инициализировать пустое пространство для хранения

2) если линия имеет менее двух разделителей, перейти к # 10

3) копировать с начала строки до (но не включая) первого разделителя на удержание

4) удалите первый сегмент линии (включая разделитель). Ведущий сегмент линии теперь должен быть токеном.

5) скопируйте токен (до разделителя) во временную переменную

6) удалите токен из линии (оставьте конечный разделитель на месте)

7) найдите токен в списке известных токенов.

8) если это известный токен, добавьте расширение токена в пространство удержания и удалите разделитель из строки. Если токен неизвестен, добавьте разделитель (удаленный в # 4) и текст токена в пространство удержания, но оставьте конечный разделитель non-token в начале строки - это разрешить (@name @@@domain @) и несколько прогонов с различными файлами определения переменных (./expstuff -v user.vars <template.in |./expstuff -v global.vars> outputfile), но вам потребуется изменение для вашего требования.

9) goto # 2

10) печатать свободное пространство и все остальное от линии.

typeset -A s

i=template.vars
d=@

while IFS='=' read t v ; do
  [[ $t != \#* ]] && s[$t]=$v
done < "$i"

while IFS= read -r l ; do
  #  assuming the @IF blah@ and corresponding @ENDIF@ occupy entire lines.
  if [[ $l == $d[Ee][Nn][Dd][Ii][Ff]$d ]]; then
    c=''
    continue
  fi
  [[ $c == '0' ]] && continue
  if [[ $l == $d[Ii][Ff][[:space:]]*[![:space:]]*$d ]]; then
    read _ t <<< "${l%$d}"
    c=0
    if [[ -n $t && ${s[$t]+t} == 't' ]]; then
      case ${s[$t]} in [Yy]|[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|1 ) c=1 ;; esac
    fi
    continue
  fi

  # Currently, given
  #   foo@domain@TLD@ wibble
  # with TLD=.co.uk
  # the following loop outputs
  #   [email protected] wibble
  # You appear to require
  #   fooError!!!TLD@wibble

  h=
  while [[ $l == *$d*$d* ]]; do
    h=$h${l%%$d*}
    l=${l#*$d}
    t=${l%%$d*}
    l=${l#$t}
    if [[ -n $t && ${s[$t]+t} == 't' ]]; then
      h=$h${s[$t]}
      l=${l#$d}
    else
      h=$h$d$t
      # for apparent requirement change preceding line to (untested)
      # h=$h"Error!!!" ; l=${l#$d}
    fi
  done
  printf '%s\n' "$h$l"
done
  • 0
    Уже немного поздно, но спасибо. Я выяснил некоторые из них самостоятельно, по сути, просто путем проб и ошибок до смерти. Не полностью исправил это так, как мне хотелось (часть вывода HONORS была немного странной, выводить, что человек был в почете, если текстовый файл просто имел строку HONORS = (что-либо кроме других символов, если FALSE, это выведите ЧЕСТИ, как если бы это было правдой, если = бла, верно. Единственный раз, когда это действовало, если почести были ложными, это если ничего не было введено. Кроме того, у меня все получилось почти идеально.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню