2017-03-28 11 views
2

J'ai un tas de sorcière fichiers latex utiliser la \input{filename.tex} macro (cela fonctionne comme un #include de C), et je veux les résoudre afin que je puisse sortie tous à un seul .tex fichier (le fichier doit être collé à la place de la macro \input{}, il est raisonnable de supposer que chaque fichier n'est référencé qu'une seule fois).Comment lire les fichiers récursive dans awk

Exemple:

tesis.tex:

My thesis. 
\input{chapter1.tex} 
More things 
\input{chapter2.tex} 

chapter1.tex:

Chapter 1 content. 

chapter2.tex:

Chapter 2 content. 
\include{section2-2.tex} 

section2-2.tex:

Section 1. 

Le résultat souhaité doit être:

My thesis. 
Chapter 1 content. 
More things 
Chapter 2 content. 
Section 1. 

S'il n'y avait qu'un niveau \input{foo.tex} je serais en mesure de résoudre ce avec ce programme AWK:

/\\input\{.*\}/{ 
    sub(/^[^{]*{/,"",$0) 
    sub(/}[^}]*$/,"",$0) 
    system("cat " $0) 
    next 
} 

{ 
    print $0 
} 

Est-il possible de lire les fichiers récursivement dans AWK?

(Je suis ouvert à le faire avec une autre langue, mais le posix Est meilleur)

Merci!

Répondre

2

Voici une solution dans awk utilisant getline dans une fonction récursive pour le travail. Je supposais chapter2.tex:

Chapter 2 content. 
\input{section2-2.tex} 

code:

$ cat program.awk 
function recurse(file) {    # the recursive function definition 
    while((getline line<file) >0) { # read parameter given file line by line 
     if(line~/^\\input/) {   # if line starts with \input 
      gsub(/^.*{|}.*$/,"",line) # read the filename from inside {} 
#   print "FILE: " line  # debug 
      recurse(line)    # make the recursive function call 
     } 
     else print line    # print records without \input 
    } 
    close(file)      # after file processed close it 
} 
{          # main program used to just call recurse() 
    recurse(FILENAME)     # called 
    exit        # once called, exit 
} 

Lancez-:

$ awk -f program.awk tesis.tex 
My thesis. 
Chapter 1 content. 
More things 
Chapter 2 content. 
Section 1. 

Solution attend \input d'être au début de l'enregistrement sans autres données sur elle.

+1

Merci! Cela résout parfaitement mon problème et peut être facilement étendu. –

+1

Ceci est similaire à ma solution bash implémentée dans awk. Je ne savais pas que awk permet aussi à une fonction de s'appeler. Cool . –

0

Puisque vous avez l'étiqueter aussi bash, quelque chose comme cela pourrait fonctionner en bash, mais il n'a pas été testé:

#!/bin/bash 
function texextract { 
while read -r line;do  
    if [[ "$line" =~ "input" || "$line" =~ "include" ]];then #regex may need finetune 
     filename="${line: 0:-1}" #removes the last } from \include{section2-2.tex} 
     filename="${filename##*{}" #removes from start up to { ---> filename=section2-2.tex 
     texextract "$filename" #call itself with new args 
    else 
     echo "$line" >>commonbigfile 
    fi 
done <"$1" #$1 holds the filename send by caller 
return 
} 

texextract tesis.tex #masterfile 

En bash 4.4 (et peut-être dans d'autres versions aussi) une fonction peut appeler lui-même. C'est ce dont je me sers ici.