Rechercher et replace le contenu d'un file

J'ai un file qui commence par quelques "inclure" des déclarations, comme ceci:

include foo.xyz include bar.xyz do c do d 

Supposons que le file foo.xyz contienne do a et que le file bar.xyz contienne do b . Comment puis-je écrire un script qui remplace chaque include file.xyz par les contexts de file.xyz ? Je veux finir avec la sortie suivante:

 do a do b do c do d 

J'ai essayé la solution dans " Remplacer la string avec le contenu d'un file en utilisant sed " mais là le nom de file est codé en dur. Je voudrais que le nom de file soit généré dynamicment, en fonction de l'argument include .

Voici une version récursive simple avec awk. Vous devez créer un script dans votre PATH avec

 #!/bin/bash awk ' $1=="include" && NF>=2 { system("'$0' " $2) next } {print}' "$@" 

Il suppose que les noms de files n'ont pas de caractères spéciaux (espaces compris) en eux. L'awk vérifie le premier mot pour inclure, puis appelle le script pour traiter le file donné comme 2ème mot. D'autres lignes sont imprimées. Notez que le $0 est en dehors des guillemets simples du awk, de même qu'un shell $0 , c'est-à-dire le nom du script.

 grep -n '^include ' yourfile | sed -e 's/:[^ ]* /{ r /' \ -e 'G;s/.$/&b&}/' | sed -nf - -ep yourfile 

ça devrait marcher. grep trouve ceux qui incluent des numéros de lignes, le premier sed modifie sa sortie en commands [num]{r fname\nb\n} spécifiques au numéro de ligne, et le second sed p rince chaque ligne qui n'est pas un des premiers scripts pour ça.

 { for x in ab do echo "do $x">"file$x.xyz" echo "include file$x.xyz" done; printf "do %s\n" cd } >yourfile cat yourfile 

 include filea.xyz include fileb.xyz do c do d 

Cela génère simplement votre échantillon et montre votre file .

Et cela fonctionne:

 grep -n '^include ' yourfile | sed -e 's/:[^ ]* /{ r /' \ -e 'G;s/.$/&b&}/' | sed -nf - -ep yourfile 

 do a do b do c do d 

les files peuvent être de n'importe quelle taille, bien entendu, et ne sont pas limités à la seule ligne. Les noms de files eux-mêmes sont limités à une seule ligne, mais sont par ailleurs plus ou less illimités (en fonction de vos sed – certains seds plus seds avaient des limites arbitraires de longueur de nom, mais la plupart d'aujourd'hui ne le font pas) .

 cat $(grep '^include' file.txt | cut -d" " -f2); grep -v '^include' file.txt 

La première command grep la ligne commençant par include dans file.txt , cut la partie du nom du file et la cat .

La command suivante imprimera toutes les lignes sauf la ligne commençant par include dans file.txt