2012-07-18 3 views
2

Je souhaite remplacer une chaîne d'un fichier par une chaîne d'un autre fichier. Bien que je ne sois pas expérimenté avec ces commandes, je pense que la combinaison de grep et sed ferait le mieux. Ce qui complique un peu la tâche, c'est que je ne sais pas ce que sont les chaînes (j'essaie d'automatiser le remplacement du numéro de version de ma documentation). Je sais que dans les deux cas la chaîne que je cherche (disons "2.3.4") est précédée de "version:"Utiliser grep et sed pour remplacer une chaîne par une autre

Donc je peux dire 'chercher mot (ou reste de ligne ou tout ce qui est possible) après "version:" (appelons-le string1) et faisons de même dans un autre fichier (en donnant string2) et remplacer string string1 par string2.

Voici quelques fichiers texte par exemple:

FILE1.TXT

Ce fichier contenant
le numéro de version mise à jour.
Version:
est 2.3.4 ici une chaîne avec plus d'infos

file2.txt

Ce fichier de configuration
Il pourrait contenir un ancien numéro de version
Version: 2.3 .2
Veuillez mettre à jour ce

Ainsi, le résultat attendu pour file2.txt deviendrait:

file2.txt

Ce fichier de configuration
Il pourrait contenir un ancien numéro de version
Version:
2.3.4 S'il vous plaît mettre à jour ce

Merci

+0

Pouvez-vous s'il vous plaît nous donner une entrée? – Debaditya

+1

Il est rare de trouver une situation où vous avez besoin de 'grep' et' sed'. Si 'grep' est assez puissant, vous n'avez pas besoin de' sed', et sinon 'sed' peut faire presque tout ce que' grep' peut faire (bien que parfois il soit torturé). – tripleee

+0

@Chronicles Bien sûr, voir la question éditée – user1488804

Répondre

2

Pourvu que vous avez un sed qui prend en charge l'option -i,

sed -i 's/version: .*/version: 1.2.3/' file1 file2 file3 ... 

Vous voudrez peut-être modifier le caractère générique regex; .* correspond à la fin de la ligne, tandis que [.0-9]* correspond à la séquence la plus longue possible de points et de chiffres. Vous pourriez aussi vouloir autoriser des variations dans les espaces environnants ... Mais puisque cela fait probablement partie des 10% de FAQ les plus fréquentes sur ce site, allez chercher des questions similaires à ce stade.

Pour obtenir la chaîne de remplacement de fichier1 et l'appliquer à fichier2, fichier3, etc., quelque chose comme

new=$(sed -n 's/version: //p' file1) 
# Use double quotes, not single, in order to expand $new 
sed -i "s/version: [.0-9]*/version: $new/" file2 file3 ... 

La première sed invocation uniquement des lignes d'impression sur laquelle « la version » a été trouvé et enlevé (remplacé avec une chaîne vide). Vraisemblablement, il n'y aura qu'une seule ligne dans le fichier.Pipe la sortie à head -n 1 ou uniq ou quelque chose, ou trouve/crée un script plus élaboré sed.

Vous utilisez normalement des guillemets simples autour des chaînes littérales, mais puisque vous ne voulez pas un $new dans le remplacement, nous utilisons des guillemets, qui permettent au shell d'effectuer un remplacement variable (et un certain nombre d'autres substitutions t aller ici) dans la chaîne entre guillemets.

+0

Je ne pense pas que la nouvelle version soit connue. –

+0

Ouais, désolé si je n'ai pas été clair. Aucun numéro de version n'est connu, car ils sont régulièrement mis à jour, et je ne voudrais idéalement pas avoir à modifier manuellement ce script à chaque changement de version. – user1488804

+0

Merci pour votre réponse. Quand je lance ceci, je trouve que l'ensemble de 'file1' est inséré dans' file2' à la place de la ligne du numéro de version. Donc je devine que quelque chose est en place avec la variable 'new' qui signifie qu'elle ne prend pas une seule ligne – user1488804

2

est-ce que ça vous convient?

kent$ head f1 f2 
==> f1 <== 
This is a file containing 
the updated version number. 
version: 2.3.4 
here is a string with more info 

==> f2 <== 
This is a configuration file 
It could contain an old version number 
version: 2.3.2 
Please update this 

kent$ awk 'NR==FNR{if($0~/^version:/){x=$0;} next;}{gsub(/^version:.*$/,x);print $0}' f1 f2 
This is a configuration file 
It could contain an old version number 
version: 2.3.4 
Please update this 
+0

En utilisant exactement ce que vous avez écrit mon f2.txt reste avec l'ancien numéro de version. Dans la ligne de commande, tous les fichiers sont imprimés sur une longue ligne (c'est-à-dire qu'ils ne conservent pas leur formatage). J'ai peur de ne pas connaître awk. Est-ce que cette commande apporte la modification au fichier, ou seulement au texte imprimé? – user1488804

+0

@ user1488804 comme vous avez vu dans ma réponse, cela a fonctionné ici. voici gawk 3.1.6 sur linux. la ligne awk ci-dessus ne changera pas votre fichier2, il imprime la sortie sur la console. – Kent

+0

Ok. Donc la commande awk n'est pas transférable alors? (J'utilise la ligne de commande Mac). Et comment le code peut-il être modifié pour que la mise à jour de la version modifie réellement le fichier texte? Merci – user1488804

Questions connexes