Outil pour créer des fichiers texte à partir d'un modèle

9

Je dois régulièrement créer plus de 100 fichiers texte à partir de modèles.
J'utilise actuellement un script shell trop compliqué. Je pense qu'il existe une façon plus intelligente de gérer cela, mais je ne sais pas comment.

J'ai une "base de données":

# outputfile      template            data1   data2    data3
first.txt         $template_main      $text1  abcd     1234
second.txt        $template_main      $text2  efgh     5678
third.txt         $template_other     $text1  ij       90

Et un fichier de configuration:

template_main=main.txt
template_other=other.txt
text1=whatever
text2=blah

Les modèles sont des fichiers texte avec des espaces réservés comme %% data2 %% (le formulaire d'espace réservé peut être modifié).

Quelqu'un connaît-il un outil pour automatiser cela mieux qu'avec un script shell compliqué?

Gregory MOUSSAT
la source
Très difficile de juger de ce qui est compliqué. L'affichage de l'un d'eux nous aidera à comprendre la situation. Essayez peut-être un script php ou perl? Qui ont un moyen plus puissant / plus facile de gérer la chaîne.
John Siu
1
Copie

Réponses:

5

Il existe probablement des milliers de ces langages de modèles et logiciels associés. Un exemple populaire est ERB , qui fait partie de Ruby vanille. Après avoir installé Ruby, vous pouvez démarrer irbou un éditeur et coller simplement l'exemple canonique pour vous en faire une idée:

require 'erb'

x = 42
template = ERB.new <<-EOF
  The value of x is: <%= x %>
EOF
puts template.result(binding)
l0b0
la source
5

Vous pourriez également envisager:

  • l'outil GNU appelé m4qui est un processeur de texte qui produit le texte que vous souhaitez prendre en entrée un modèle avec les parties à modifier. Ce serait sûrement plus simple qu'un script shell. (il fonctionne plus ou comme un préprocesseur C avec la macro #define IIRC).

  • l'outil GNU xsltprocqui applique une transformation et vous donne la sortie. Le modèle est dans xml, et xsltest le format des choses de transformation à faire à votre xmlafin de sortir du texte.

Personnellement, j'ai une préférence pour xslt, mais dans votre cas, cela ne correspondrait pas aux champs du formulaire %DATA1% %DATA2%. Il a besoin de XML, donc vous détesteriez changer vos modèles.

Ainsi, vous devriez vraiment y jeter un œil m4.

  • Comme autre choix, on m'a dit que le Haskelllangage de programmation est vraiment très bon pour transformer les flux. Je ne considère cette idée que parce que les amateurs de Haskell parlent du merveilleux Parsecpaquet, qui permet une analyse naturelle des flux de chaînes. Beaucoup mieux que xslt, qui est déjà bon. Je ne fais que les répéter, parce que je suis en train d'apprendre Haskell, et je n'ai pas la moindre idée de comment transformer du texte avec lui pour l'instant .
Stéphane Rolland
la source
2

Je pense que vous feriez mieux de regarder un vrai langage de script, comme PHP, Perl ou Python, pour faire quelque chose comme ça, surtout si vous ne voulez vraiment pas entrer dans des scripts shell complexes à grande échelle.

AVP
la source
J'appuie ceci, quand je dois faire de telles opérations de munging de texte, j'attrape Perl (mais Python ou Ruby devraient faire aussi bien). Mieux vaut utiliser un outil régulier et très utilisé que vous connaissez bien (même s'il n'est pas adapté à 100% à l'emploi) qu'un programme spécialisé que vous utilisez rarement (et qui, tôt ou tard , tombera en quelque sorte).
vonbrand
2

Je ne sais pas pourquoi vous faites cela, mais vous avez deux modèles ici. L'un est votre «base de données» et l'autre est votre véritable modèle. Les deux sont faciles à manipuler avec shtpl . (mon projet privé, donc peu utilisé, mais a été développé pour résoudre réellement ce genre de problèmes)

Avec shtpl, vous feriez quelque chose comme ceci:

Contenu du fichier 'configuration':

template_main=main.txt
template_other=other.txt
text1=whatever
text2=blah

Contenu du fichier 'base de données' (j'ai supposé que le délimiteur est tab (\ t)):

#% . "$CONFFile"
#% if [ -z "$template_main" ] || [ -z "$template_other" ] || \
#%    [ -z "$text1" ]         || [ -z "$text2" ]; then
#%   printf "database could not be generated!\n" > /dev/stderr
#%   exit 1
#% fi
#%# outputfile  template        data1   data2   data3
first.txt       $template_main  $text1  abcd    1234
second.txt      $template_main  $text2  efgh    5678
third.txt       $template_other $text1  ij      90

Contenu de generatetemplates.sh:

#!/bin/bash

if [ ! -s "$CONFFile" ]; then
 if [ ! -s "$1" ]; then
   printf "CONFfile is not set or empty!\n"
   exit 1
 else
   export CONFFile="$1"
 fi
fi

DB="$( bash -c "$( shtpl database )" )"
if [ -z "$DB" ]; then
  printf "Database is empty! Abort.\n"
  exit 2
fi
IFS=$'\t'
printf "%s" "$DB" | while read "Out" "In" "data1" "data2" "data3"; do

  data1="$data1" data2="$data2" data3="$data3" \
  bash -c "$( shtpl "$In" )" > "$Out"

done

Contenu de main.txt (other.txt est tout à fait le même):

main.txt template
$data1
$data2
$data3

Donc, exécuter generatetemplates.sh

$ bash generatetemplates.sh "./configuration"

nous génère first.txt, second.txt et third.txt.

$ cat first.txt    | $ cat second.txt   | $ cat third.txt
main.txt template  | main.txt template  | other.txt template
whatever           | blah               | whatever
abcd               | efgh               | ij
1234               | 5678               | 90

Petite explication: dans generatetemplates.sh se trouve d'abord la «base de données» nécessaire générée à partir de votre fichier de configuration. Et deuxièmement pour chaque tupel de la base de données, enfin le fichier Out correspondant de votre In-template.

Remarque: Une donnée vide [123] pose problème. Ce n'est donc pas possible avec cette approche.

Alors, espérons que c'est assez simple pour vos besoins.

S'amuser!

zstegi
la source
1

J'ai récemment publié un projet open source qui accomplit exactement cela en utilisant une syntaxe de modèle de type jinja. Cela s'appelle un cookie . Voici une démo:

démo de cookie

Bryan Bugyi
la source
1

Consultez tcat.sh . Supposons que vous ayez un fichier modèle:

hello ${name}

puis

$ export name=world # or load and export from a properties file.
$ ./tcat.sh template-file

Production:

hello world
Dagang
la source