2010-12-07 23 views

Répondre

3

Si vous êtes d'accord avec Perl, vous pouvez le faire:

$ cat FILE1 
this is file1 

$ cat FILE2 
this is file2 

$ cat file 
foo 
INSERT_HERE1 
bar 
INSERT_HERE2 
baz 

$ perl -ne 's/^INSERT_HERE(\d+)\s+$/`cat FILE$1`/e;print' file 
foo 
this is file1 
bar 
this is file2 
baz 
$ 
+0

hum .. Je voudrais garder les dépendances vers le bas. Est-ce que perl est aussi commun d'avoir installé, disons, sed? – aioobe

+0

@aioobe Oui. Je ne connais aucun système Unix moderne qui n'inclut pas Perl. – Jonathan

+0

@aioobe Oui. Perl est omniprésent. – codaddict

1

Ce n'est pas testé, mais serait assez proche de ce que vous avez besoin:

sed -e "s/INSERT_HERE1/`cat file1.txt`/" -e "s/INSERT_HERE2/`cat file2.txt`/" <file >file.out 

Il ne sera pas gérer correctement un fichier avec des barres obliques dans, cependant, vous devrez peut-être modifier un peu.

Je recommanderais plutôt Perl, cependant. Quelque chose comme ceci:

#!/usr/bin/perl -w 

my $f1 = `cat file1.txt`; 
my $f2 = `cat file2.txt`; 

while (<>) { 
    chomp; 
    s/INSERT_HERE1/$f1/; 
    s/INSERT_HERE2/$f2/; 
    print "$_\n"; 
} 

Cela suppose que INSERT_HERE1 et INSERT_HERE2 ne peuvent apparaître qu'une seule fois par ligne, et que le file1.txt ne comprend pas le texte INSERT_HERE2 (ne serait pas difficile de fixer, cependant). Utilisez comme ceci:

./script <file >file.out 
+0

Oh, bien sûr. Je voudrais aller avec Perl mais je vais laisser les autres utiliser ce script, donc je veux garder les dépendances vers le bas. Je vais essayer votre sed-line! – aioobe

+0

hmm .. le sed-line ne semble pas fonctionner. C'est peut-être parce que 'fichier1.txt' contient des caractères tels que' '' '. – aioobe

+0

Je ne pense pas qu'il soit possible de le faire dans 'sed' et de permettre au fichier d'entrée de contenir n'importe quel caractère. Je ne sais pas «awk», malheureusement, donc je ne peux pas dire s'il y a une meilleure solution là-bas. Quel genre de système êtes-vous où 'sed' est standard mais' perl' ne l'est pas? – Jonathan

1

Ceci est approprié pour de petits fichiers de substitution qui peuvent être substitués plusieurs fois:

awk 'BEGIN { 
     while ((getline line < ARGV[1]) > 0) {file1 = file1 nl line; nl = "\n"}; 
     close (ARGV[1]); nl = ""; 
     while ((getline line < ARGV[2]) > 0) {file2 = file2 nl line; nl = "\n"}; 
     close (ARGV[2]); 
     ARGV[1] = ""; ARGV[2] = "" } 
     { gsub("token1", file1); 
     gsub("token2", file2); 
     print }' file1.txt file2.txt mainfile.txt 

Vous Vous voudrez peut-être ajouter quelques lignes supplémentaires ici et là, selon la façon dont vous voulez que votre sortie apparaisse.

+0

Je passerais le contenu du fichier en tant que variables: 'awk -v" f1 = $ (

+0

@glenn: C'est une autre façon Comme je le montre, il est facile de passer les noms de fichiers comme arguments et de pré-traiter pendant la lecture, si désiré. –

1

Facile à utiliser avec Bash. Si vous avez besoin d'être POSIX me faire savoir:

#!/bin/bash 

IFS= # Needed to prevent the shell from interpreting the newlines 
f1=$(< /path/to/file1.txt) 
f2=$(< /path/to/file2.txt) 

while read line; do 
    if [[ "$line" == "INSERT_HERE1" ]]; then 
    echo "$f1" 
    elif [[ "$line" == "INSERT_HERE2" ]]; then 
    echo "$f2" 
    else 
    echo "$line" 
    fi 
done < /path/to/input/file 
8

Sed a une commande de fichier de lecture intégré. Les commandes que vous voulez ressemblerait à quelque chose comme ceci:

$ sed -e '/INSERT_HERE1/ { 
r FILE1 
d }' -e '/INSERT_HERE2/ { 
r FILE2 
d }' < file 

Cette génèrerait

foo 
this is file1 
bar 
this is file2 
baz 

La commande r lit le fichier, et la commande d supprime la ligne avec les balises INSERT_HERE. Vous devez utiliser les accolades depuis les commandes sed et les entrées multiligne puisque les commandes sed doivent démarrer sur leur propre ligne, et en fonction de votre shell, vous pouvez avoir besoin de \ à la fin des lignes pour éviter une exécution prématurée. Si c'est quelque chose que vous utiliseriez beaucoup, vous pouvez simplement placer la commande dans un fichier et utiliser sed -f pour l'exécuter.

+1

hm, cela ne semble fonctionner qu'avec INSERT_HERE1 et INSERT_HERE2 étant un seul mot sur un seul ligne, sinon toute la ligne de texte sera remplacée? – dothebart

0

Cet extrait remplace toute section spécifiée dans le tableau supérieur. Par exemple ici

<!--insert.txt--> 

avec le contenu de "insert.txt"

#!/bin/bash 

replace[1]=\<!--insert.txt--\>  ; file[1]=insert.txt 
replace[2]=\<!--insert2.txt--\>  ; file[2]=insert2.txt 

replacelength=${#replace[@]} 

cat blank.txt > tmp.txt 
for i in $(seq 1 ${replacelength}) 
do 
    echo Replacing ${file[i]} ... 
    sed -e "/${replace[i]}/r ${file[i]}" -e "/${replace[i]}/d" tmp.txt > tmp_2.txt 
    mv tmp_2.txt tmp.txt 
done 
mv tmp.txt file.txt 

Si vous n'êtes pas peur.les fichiers zip que vous pouvez essayer cet exemple aussi longtemps qu'il est en ligne: http://ablage.stabentheiner.de/2013-04-16_contentreplace.zip

0

J'utiliser des années perl en place de remplacement avec -i.ext l'option

perl -pi.bak -e 's|INSERT_HERE1|`cat FILE1`|ge; 
       s|INSERT_HERE2|`cat FILE2`|ge;' myfile 

Ensuite, utilisez diff myfile.bak myfile pour vérifier: