J'ai été chargé de remplacer un grand nombre d'identifiants codés en dur dans certains codes (par exemple: private static String MERCHANT_ID = "1234";
) avec des références à un fichier de configuration quelque part (la version remplacée pour cet exemple doit donc être private static String MERCHANT_ID = ConstantMerchants.MERCHANT_A;
).
La fonction de recherche et de remplacement par défaut dans Eclipse aurait ça ira si je ne remplaçais que quelques pièces d'identité, mais je ne le suis pas. J'ai vingt projets, tous contiennent des centaines de fichiers avec plusieurs notations différentes de l'ancienne chaîne.
J'ai déjà compilé une liste de motifs de regex qui correspondent à toutes les notations possibles.
Est-il possible d'utiliser sed pour remplacer toutes les anciennes chaînes par les nouvelles versions en disposant un fichier de configuration quelque part contenant l'ancien modèle, et par quoi il devrait être remplacé?
Je cherche quelque chose qui me permette de définir des motifs avec une nouvelle valeur, pensez à quelque chose de similaire à ceci:
# old | new
/merchantId:\s*("|')1234("|'),/|merchantId: ConstantMerchants.MERCHANT_A
/private static String MERCHANT_ID\s*=\s*("|')1234("|');/|private static String MERCHANT_ID = ConstantMerchants.MERCHANT_A
Si je devais utiliser un autre outil qui pourrait m'aider à mieux résoudre ce problème, j'aimerais en entendre parler. J'aimerais beaucoup utiliser la nouvelle fonctionnalité Bash sur Windows, mais c'est uniquement parce qu'elle a l'air cool :)
la source
sed
syntaxe, ou ne pouvez-vous pas obtenirsed
travailler sur plusieurs fichiers, ou quoi?sed
commande qui effectue tous les remplacements, en utilisant plusieurs fichiers regex etsed
vous pouvez utiliser le-e
possibilité de faire autant de substitutions à autant de fichiers que nécessaire en une seule fois, par exemplesed -i -e 's/old1/new1/' -e 's/old2/new2' ... file1 file2 ...
. Si les fichiers ne se trouvent pas tous dans un seul répertoire ou au même niveau dans une arborescence de sous-répertoires, vous permettant de les sélectionner avec une correspondance de caractère générique, vous pouvez utiliserfind
etxargs
pour construire la chaîne d'exécution.sed
, ce est une bonne référence.Réponses:
Si je comprends bien, le problème est que vous avez un ensemble de modèles de syntaxe à faire correspondre, et indépendamment, un grand nombre de nombres possibles devant être traduits, et vous devez les "multiplier" ensemble. Ce qui suit pourrait être un bon
sed
mécanisme, en supposant une simplification: dans votresed
Commencez par utiliser les modèles pour faire correspondre les lignes, puis utilisez la conversion de nombre sur ces lignes. Par exemple créer un fichiersedscript
en portantCela commence par chacun de vos patterns suivi de la commande
b change
ce qui signifie branche à l'étiquettechange
quand le motif est trouvé. La liste des modèles se termine par la commandeb
ce qui signifie aller à la fin, c’est-à-dire passer à la prochaine ligne d’entrée du fichier.le
:change
signifie que c'est l'étiquettechange
où nous branchons à. Suit ensuite chacun de vos numéros possibles pour nommer les traductions. La simplification consiste à supposer qu’un seul nombre entre guillemets apparaîtra sur la ligne afin que nous puissions ignorer quel modèle correspond. S'il y a des exceptions à cela, il peut être intéressant de les gérer à la main.Sur un système Unix (je ne connais pas Windows), vous pouvez utiliser ce script pour éditer les fichiers:
le
-i
éditera les fichiers sur place, donc commencez toujours par copier les fichiers vers un nouveau répertoiredir
, puis exécutez cette commande sur la copie et utilisezdiff -ru
entre les deux répertoires pour vérifier qu’il fait ce que vous voulez. le-r
est nécessaire (sous Unix) pour que GNU sed accepte(a|b)
au lieu de l'habituel\(a\|b\)
modèle.la source
change
label permet également de réduire le nombre de commandes à ajouter.En regardant le HOMME Page vous verrez que
sed
soutient un-f
paramètre pour fournir un fichier de script. Ce fichier doit contenir tous les éléments de remplacement à exécuter comme vous le fournissez.sed
directement. Donc, par exemple vous auriez:s/old/new/
s/new/old/
Sur des lignes séparées du fichier, les deux commandes seront appliquées à tout ce que vous fournissez en
stdout
. Par exemple:echo "old" | sed -f script.file
avec le contenu ci-dessus conduirait à la sortie ancienne.Pour appliquer ces règles à plusieurs fichiers, une option serait d’utiliser une boucle dans laquelle vous exécutez
sed
avec le script pour chaque fichier et enregistrez les modifications apportées au fichier lui-même. Une autre serait d'utiliser l'option-i
et fournit "tous" les fichiers comme arguments de ligne de commande. En fonction du nombre, vous pouvez rencontrer des problèmes avec la longueur totale de la commande.la source
sed
. Je suis sûr qu'il est possible de faire quelque chose comme ça, mais pas comment.