Suite

Rechercher et remplacer le script source du fichier de formes ne fonctionne pas


Je suis très nouveau sur python alors veuillez me pardonner s'il s'agit d'une simple erreur. J'ai pas mal de MXD dans lesquels chacun a quelques couches référençant la même source. Cependant, j'ai depuis déplacé ces données dans un nouveau dossier. J'ai écrit un script pour actualiser automatiquement les calques similaires.

Le script s'exécute, cependant, lorsque je vérifie si cela fonctionne, aucune des couches n'est actualisée. Je ne suis pas sûr de ce qui ne va pas.

importer arcpy, os #workspace pour rechercher des MXDs Workspace = r"M:TEAM_GISEDKMProjectsmmo1065_south_habitat_mapping20140708_Update_3_QA3_Working_GIS_FilesMXD" arcpy.env.workspace = Workspace #list map documents = folder mxdList "*.mxd") print mxdList #définir un nouveau lien pour un fichier de formes spécifique dans chaque MXD de la liste. pour le fichier dans mxdList : #définir la carte pour modifier filePath = os.path.join(Workspace, file) mxd = arcpy.mapping.MapDocument(filePath) pour lyr dans arcpy.mapping.ListLayers(mxd) : si lyr.supports( "DATASOURCE") : si lyr.dataSource == r"M:TEAM_GISEDKMProjectsmmo1065_south_habitat_mapping20140708_Update_3_QA3_Working_GIS_FilesWP1MMO_South_Plan_Areas.shp": lyr.findAndReplaceWorkspacePath:lyr.findAndReplaceWorkspacePath: mmo1065_south_habitat_mapping20140708_Update_3_QA3_Working_GIS_FilesWP1", r"M:TEAM_GISEDKMProjectsmmo1065_south_habitat_mapping20140708_Update_3_QA3_Working_GIS_FilesEDKMProjectsmmo1065_south_habitat_mapping20140708_Update_3_QA3_Working_GIS_Files2014. 3_Working_GIS_FilesWP1Land.shp" : lyr.findAndReplaceWorkspacePath(r"M:TEAM_GISEDKMProjectsmmo1065_south_habitat_mapping20140708_Update_3_QA3_Working_GIS_FilesWP1", r"Mping_08maTEAM3 SHP") arcpy.RefreshTOC() arcpy. RefreshActiveView() mxd.save() affiche "Succès"

Comme l'a commenté @Luke, et alors que nous travaillions tous les deux à :

S'il s'agit de votre code réel, votre for lyr dans arcpy.mapping.ListLayers(mxd): boucle ne s'exécutera que sur le mxd final car il n'est pas en retrait pour être à l'intérieur du fichier for dans mxdList: loop.

Au lieu de votre code, essayez :

importer arcpy, os #workspace pour rechercher des MXDs Workspace = r"M:TEAM_GISEDKMProjectsmmo1065_south_habitat_mapping20140708_Update_3_QA3_Working_GIS_FilesMXD" arcpy.env.workspace = Workspace #list map documents = folder mxdList "*.mxd") print mxdList #définir un nouveau lien pour un fichier de formes spécifique dans chaque MXD de la liste. pour le fichier dans mxdList : #définir la carte pour modifier filePath = os.path.join(Workspace, file) mxd = arcpy.mapping.MapDocument(filePath) pour lyr dans arcpy.mapping.ListLayers(mxd) : si lyr.supports( "DATASOURCE") : si lyr.dataSource == r"M:TEAM_GISEDKMProjectsmmo1065_south_habitat_mapping20140708_Update_3_QA3_Working_GIS_FilesWP1MMO_South_Plan_Areas.shp": lyr.findAndReplaceWorkspacePath:lyr.findAndReplaceWorkspacePath: mmo1065_south_habitat_mapping20140708_Update_3_QA3_Working_GIS_FilesWP1", r"M:TEAM_GISEDKMProjectsmmo1065_south_habitat_mapping20140708_Update_3_QA3_Working_GIS_FilesEDKMProjectsmmo1065_south_habitat_mapping20140708_Update_3_QA3_Working_GIS_Files2014. 3_Working_GIS_FilesWP1Land.shp" : lyr.findAndReplaceWorkspacePath(r"M:TEAM_GISEDKMProjectsmmo1065_south_habitat_mapping20140708_Update_3_QA3_Working_GIS_FilesWP1", r"Mping_08maTEAM3 SHP") mxd.save() print "Succès "

J'ai supprimé les arcpy.RefreshActiveView() et arcpy.RefreshTOC() car ils ne font quelque chose que lorsque votre objet MapDocument a été créé à l'aide de "CURRENT".


Rechercher et remplacer à l'aide d'expressions régulières

J'ai un fichier avec un tas de valeurs par défaut de l'utilisateur. Je veux changer une partie du texte, mais j'ai du mal à trouver un matcher et un remplaçant. En utilisant l'exemple suivant :

J'aimerais remplacer # Trackpad : . en exécutant « Trackpad : . »

En décomposant le problème, j'ai trouvé quelque chose à l'aide d'un testeur d'expression régulière :

Si j'essaie d'utiliser ceci dans Vim, cela ne fonctionne pas pour moi :

Je suppose que mon problème se résume à deux questions spécifiques :

  1. Comment puis-je éviter de rechercher les caractères et m'assurer à la place que # n'apparaît pas à la fin du groupe de recherche ?
  2. Comment puis-je utiliser efficacement les groupes de capture ?

Il y a quelques bonnes réponses ci-dessous. Difficile de choisir entre les trois, mais je pense que la réponse choisie est la plus précise pour ma spécification d'origine. Je vous recommande d'essayer les trois réponses avec le fichier réel pour voir ce que vous en pensez.


3 réponses 3

Je suggère d'utiliser le ccommande hange (qui est essentiellement une elete couplé à un uneppend, bien que l'ajout ne soit appliqué que pour la dernière ligne de la plage, ce qui est exactement ce que vous voulez ici):

Ici, en utilisant la syntaxe de GNU sed pour l'édition sur place ( -i ). Cette commande c est par ailleurs standard et portable. GNU sed prend en charge :

en tant qu'extension non standard.

Les caractères de nouvelle ligne et de barre oblique inverse doivent être échappés (avec barre oblique inverse) dans le texte de remplacement.

Utiliser GNU sed

Pour remplacer les lignes commençant par une ligne correspondant à 3 et continuant jusqu'à une ligne correspondant à 5 par New Code :

Pour les lignes dans la plage /3/,/5/ , nous testons pour voir si la ligne correspond à 5 (ce qui signifie qu'il s'agit de la dernière ligne du groupe) et, si c'est le cas, nous effectuons la substitution pour insérer un nouveau code . Si la substitution a été effectuée, alors la commande t indique à sed de sauter à la fin des commandes (auquel cas le nouveau code est affiché). Sinon, la commande d dit à sed de supprimer la ligne.

Toutes les autres lignes sont imprimées normalement.

Pour changer le fichier en place, l'option -i peut être utilisée :

Utiliser awk

La commande awk traite spécialement les lignes dans la plage /3/,/5/. Pour les lignes de cette plage, nous testons pour voir si f est égal à zéro (c'est-à-dire si !f est vrai) et, si c'est le cas, nous imprimons New Code et définissons f à 1, puis nous sautons le reste des commandes et sautons à la ligne suivante.

Pour les lignes en dehors de la plage /3/,/5/ , aucun saut n'est effectué et le 1 provoque l'impression de la ligne. Plus en détail, 1 est une condition. Comme 1 n'est pas zéro, la condition est vraie. Etant donné qu'aucune action n'est associée à la condition, l'action par défaut est exécutée et consiste à imprimer la ligne. Ainsi, 1 est un raccourci pour print-the-line.

Pour modifier un fichier en place, l'option -i inplace peut être utilisée avec GNU awk 4.1 ou supérieur :


Homme pax

. Les comparaisons de temps utilisant les deux temps de fichier sont utiles lorsque pax est utilisé pour créer une archive incrémentielle basée sur le temps (seuls les fichiers qui ont été modifiés pendant une période spécifiée seront archivés).

Une plage de temps est composée de six champs différents et chaque champ doit contenir deux chiffres. Le format est :

Où cc est les deux premiers chiffres de l'année (le siècle), yy est les deux derniers chiffres de l'année, le premier mm est le mois (de 01 à 12), jj est le jour du mois (de 01 à 31 ), HH est l'heure du jour (de 00 à 23), MM est la minute (de 00 à 59) et SS est les secondes (de 00 à 59). Le champ minute MM est obligatoire, tandis que les autres champs sont facultatifs et doivent être ajoutés dans l'ordre suivant :

Le champ SS peut être ajouté indépendamment des autres champs. Les plages de temps sont relatives à l'heure actuelle, donc.

. sélectionnerait tous les fichiers avec une heure de modification ou de changement d'inode de 12h34 aujourd'hui ou plus tard.

Plusieurs plages de temps -T peuvent être fournies et la vérification s'arrête avec la première correspondance.

. donc le 11 là-haut dans mon exemple de commande est relatif à aujourd'hui - c'est un de moins que la date d'aujourd'hui - qui est le douzième - et le reste est juste un format standard "$(date)" suivi d'une virgule.

. sauf - et la dernière chose à mentionner - j'utilise un chemin absolu pour le répertoire cible - et vous devriez le faire si vous le faites. Les docs font toutes référence comportement non spécifié pour les chemins cibles relatifs - et la première fois que j'ai essayé d'utiliser pax, je jurais dans ma barbe pendant une heure dans la confusion avec tous les résultats étranges jusqu'à ce que j'utilise un chemin absolu.


  • s = la commande de substitution
  • original = une expression régulière décrivant le mot à remplacer (ou juste le mot lui-même)
  • new = le texte par lequel le remplacer
  • g = global (c'est-à-dire remplacer tout et pas seulement la première occurrence)

Il existe une multitude de façons d'y parvenir. Selon la complexité de ce que l'on essaie de réaliser avec le remplacement de chaîne, et selon les outils avec lesquels l'utilisateur est familier, certaines méthodes peuvent être préférées à d'autres.

Dans cette réponse, j'utilise un simple fichier input.txt, que vous pouvez utiliser pour tester tous les exemples fournis ici. Le contenu du fichier :

Bash n'est pas vraiment destiné au traitement de texte, mais des substitutions simples peuvent être effectuées via l'expansion des paramètres , en particulier ici, nous pouvons utiliser la structure simple $ .

Ce petit script ne fait pas de remplacement sur place, ce qui signifie que vous devrez enregistrer le nouveau texte dans un nouveau fichier et vous débarrasser de l'ancien fichier, ou mv new.txt old.txt

Note latérale : si vous êtes curieux de savoir pourquoi alors que IFS= read -r do . done < input.txt est utilisé, c'est essentiellement la façon dont le shell lit le fichier ligne par ligne. Voir ceci pour référence.

AWK, étant un utilitaire de traitement de texte, est tout à fait approprié pour une telle tâche. Il peut effectuer des remplacements simples et des remplacements beaucoup plus avancés basés sur des expressions régulières. Il fournit deux fonctions : sub() et gsub() . Le premier ne remplace que la première occurrence, tandis que le second remplace les occurrences dans la chaîne entière. Par exemple, si nous avons une chaîne une pomme de terre deux pomme de terre , ce serait le résultat :

AWK peut prendre un fichier d'entrée comme argument, donc faire la même chose avec input.txt serait facile :

Selon la version d'AWK que vous possédez, il peut ou non avoir une édition sur place, d'où la pratique habituelle est d'enregistrer et de remplacer le nouveau texte. Par exemple quelque chose comme ceci :

Sed est un éditeur de ligne. Il utilise également des expressions régulières, mais pour des substitutions simples, il suffit de faire :

Ce qui est bien avec cet outil, c'est qu'il dispose d'une édition sur place, que vous pouvez activer avec l'indicateur -i.

Perl est un autre outil souvent utilisé pour le traitement de texte, mais c'est un langage à usage général, utilisé dans les réseaux, l'administration système, les applications de bureau et bien d'autres endroits. Il a emprunté de nombreux concepts/fonctionnalités à d'autres langages tels que C, sed, awk et autres. Une substitution simple peut être effectuée de la manière suivante :

Comme sed, perl a aussi le drapeau -i.

Python

Ce langage est très polyvalent et est également utilisé dans une grande variété d'applications. Il a beaucoup de fonctions pour travailler avec des chaînes, parmi lesquelles replace() , donc si vous avez une variable comme var="Hello World" , vous pouvez faire var.replace("Hello","Good Morning")

Un moyen simple de lire le fichier et d'y remplacer la chaîne serait le suivant :

Avec Python, cependant, vous devez également générer un nouveau fichier , ce que vous pouvez également faire à partir du script lui-même. Par exemple, en voici un simple :

Ce script doit être appelé avec input.txt comme argument de ligne de commande. La commande exacte pour exécuter le script python avec l'argument de ligne de commande serait

Bien sûr, assurez-vous que ./myscript.py est dans votre répertoire de travail actuel et pour la première manière, assurez-vous qu'il est défini comme exécutable avec chmod +x ./myscript.py

Python peut également avoir des expressions régulières, en particulier, il y a le module re, qui a la fonction re.sub(), qui peut être utilisée pour des remplacements plus avancés.

Il existe différentes manières de procéder. L'un utilise sed et Regex. SED est un éditeur de flux pour filtrer et transformer du texte. Un exemple est le suivant :

Une autre façon qui peut avoir plus de sens que < strin et > strout est d'utiliser des tuyaux !

5 fois plus rapide. &ndash pbhj 22 octobre 17 à 20:14

Vous pouvez utiliser Vim en mode Ex :

g remplacer toutes les instances dans chaque ligne

x écrire si des modifications ont été apportées (elles l'ont été) et quitter

Grâce à la commande gsub d'awk,

Dans l'exemple ci-dessus, tous les 1 sont remplacés par des 0 quelle que soit la colonne où ils se trouvent.

Si vous voulez faire un remplacement sur une colonne spécifique, alors faites comme ceci,

Il remplace 1 par 0 sur la première colonne uniquement.

sed est le strébucher editor, en ce sens que vous pouvez utiliser | (tuyau) envoyer flux standards (STDIN et STDOUT en particulier) via sed et modifiez-les par programmation à la volée, ce qui en fait un outil pratique dans la tradition de la philosophie Unix, mais peut également éditer des fichiers directement, en utilisant le paramètre -i mentionné ci-dessous.
Considérer ce qui suit:

s/ est utilisé pour sremplacer l'expression trouvée par asd :

/g signifie "global", ce qui signifie le faire pour toute la ligne. Si vous omettez le /g (avec s/few/asd/ , il doit toujours y avoir trois barres obliques quoi qu'il arrive) et que peu apparaissent deux fois sur la même ligne, seuls les premiers sont remplacés par asd :

Les quelques hommes, les quelques femmes, les braves.

Les hommes asd, les quelques femmes, les braves.

Ceci est utile dans certaines circonstances, comme la modification des caractères spéciaux au début des lignes (par exemple, en remplaçant les symboles supérieur à que certaines personnes utilisent pour citer le matériel précédent dans les fils de discussion par une tabulation horizontale tout en laissant une inégalité algébrique entre guillemets plus tard dans la ligne intact), mais dans votre exemple où vous spécifiez que partout peu se produit, il doit être remplacé, assurez-vous d'avoir ce /g .

Les deux options (drapeaux) suivantes sont combinées en une seule, c'est-à-dire :

L'option -i est utilisée pour éditer jen placez sur le fichier hello.txt .

L'option -e indique le expression/commande à exécuter, dans ce cas s/ .

Remarque : Il est important que vous utilisiez -i -e pour rechercher/remplacer. Si vous faites -ie , vous créez une sauvegarde de chaque fichier avec la lettre 'e' ajoutée.


Ici, j'utilise sed pour remplacer chaque occurrence du mot "cybernetnews" par "cybernet" dans chaque fichier avec l'extension c dans le répertoire /home/user/directory/.

Une variante plus générique où vous effectuez une recherche récursive à partir du répertoire d'exécution et n'opérez que sur des fichiers réguliers, lisibles et inscriptibles :

L'éditeur de flux, sed, est un utilitaire puissant pour ce genre de travail et est mon premier choix, cependant, si vous voulez le faire à partir d'un éditeur de texte ordinaire en utilisant une application native basée sur Ubuntu, je vous suggère de jeter un œil à Jedit , Il est disponible dans les dépôts et peut être installé en tapant dans votre console :

Démarrez jedit, cliquez sur l'élément de menu de recherche, dans la liste de menu, cliquez sur l'élément Rechercher dans le répertoire, la boîte de dialogue ci-dessous s'affichera :

Ceci est similaire à celui de Notepad ++ et fait la même chose, je crois que c'est ce que vous voulez.


Rechercher et remplacer plusieurs valeurs différentes à la fois

J'ai un fichier avec plusieurs instances de Text_1 et Text1 et je dois remplacer ces deux chaînes par Text_A et TextB respectivement.

Actuellement, je fais deux fonctions Find and Replace sur chaque fichier, l'une qui trouve Text_1 et le remplace par Text_A et l'autre qui trouve Text1 et le remplace par TextB .

Existe-t-il un moyen de tout faire en même temps au lieu d'exécuter deux fois "Rechercher et remplacer" ?

J'utilise Dreamweaver CS3, mais j'ai aussi le Bloc-notes ++, le Bloc-notes normal, OO Writer, MS Word si cela est plus facile. Idéalement, je pourrais le faire dans Dreamweaver ou Notepad ++, mais je suis prêt à télécharger autre chose pour faire le travail. Je préférerais ne pas avoir à faire de ligne de commande ou à créer un fichier batch (bien que j'en sois conscient, je ne le comprends pas vraiment).

Au cas où la description ci-dessus n'est pas claire, laissez-moi l'expliquer de cette façon.

Je veux exécuter Rechercher et remplacer Une fois dans 1 document et je veux que ça le fasse TOUS des éléments suivants au cours de cette instance Find & Replace :

  1. Trouver Text_1 et Remplacer avec Text_A
  2. Trouver Texte1 et Remplacer avec TextB

Je suis ne pas essayer de faire une recherche et un remplacement sur plusieurs documents.


9 réponses 9

C'est en fait assez simple avec sed : si une ligne correspond, copiez-la simplement dans l'espace réservé, puis remplacez la valeur.
Sur la ligne la $ t e ​​x changez l'espace de maintien et l'espace de motif puis vérifiez si ce dernier est vide. S'il n'est pas vide, cela signifie que la substitution a déjà été effectuée donc rien à faire. S'il est vide, cela signifie qu'aucune correspondance n'a été trouvée, alors remplacez l'espace de motif par l'espace souhaité variable=valeur puis ajouter à la ligne actuelle dans le tampon de maintien. Enfin, e x changez à nouveau :


Pour votre remplacement, vous souhaitez seulement insérer un espace. [:space:] ne fonctionnera pas là car c'est l'abréviation d'une classe de caractères et le moteur de regex ne saurait pas quel caractère y mettre.

Le + doit être échappé dans la regex car avec le moteur de regex de sed, + est un caractère normal alors que + est un métacaractère pour 'un ou plusieurs'. À la page 86 de Maîtriser les expressions régulières, Jeffrey Friedl mentionne dans une note de bas de page que ed et grep utilisaient des parenthèses échappées parce que "Ken Thompson a estimé que les expressions régulières seraient utilisées principalement avec du code C, où la nécessité de faire correspondre des parenthèses brutes serait plus courante que le retour en arrière". Je suppose qu'il ressentait la même chose à propos du signe plus, d'où la nécessité de l'échapper pour l'utiliser comme métacaractère. Il est facile de se faire trébucher par ça.

Dans sed, vous devrez vous échapper + , ? , | , ( , et ) . ou utilisez -r pour utiliser une expression régulière étendue (alors cela ressemble à sed -r -e "s/[[:space:]]+/ /g" ou sed -re "s/[[:space:]]+ / /g"


va ici
http://gnuwin32.sourceforge.net/packages.html
faites défiler jusqu'à SED. Téléchargez coreutils pendant que vous y êtes.

cette commande remplacera a par b globalement, et sur chaque ligne. donc pas seulement la première occurrence sur la ligne.

VBScript prend en charge les expressions régulières, vous pouvez les rechercher et les remplacer.

J'ai écrit un outil de ligne de commande gratuit pour Windows pour ce faire. Il s'appelle rxrepl, il prend en charge Unicode et la recherche de fichiers. Certains peuvent trouver qu'il s'agit d'un outil utile.

rxrepl est un outil de ligne de commande Microsoft Windows permettant de rechercher et de remplacer du texte dans des fichiers texte à l'aide d'expressions régulières compatibles Perl (PCRE).

Il a les caractéristiques suivantes :

  • Recherche à l'aide d'expressions régulières compatibles Perl
  • Utiliser la correspondance de groupe dans le texte de remplacement
  • Prend en charge les fins de ligne Windows et Unix
  • Prise en charge d'Unicode
  • Accepte plusieurs arguments de recherche/remplacement
  • Les options peuvent être fournies dans un fichier d'options
  • Rechercher des fichiers
  • Mode aperçu
  • Modes de correspondance de ligne et de fichier complet

The Scripting Guy explique comment procéder dans PowerShell (pas de téléchargements supplémentaires sur les systèmes d'exploitation Windows les plus récents, vous l'avez probablement déjà installé).

Démarrez-le, exécutez ce qui suit (pour remplacer un * par un @ ):

Cela prend en charge les expressions régulières .NET, y compris les prévisions positives et négatives, et toutes sortes de choses que notepad++ ne prenait pas en charge avec regex avant la version 6.x (autant que j'aime notepad++).

J'ai trouvé fnr.exe pour cela. Il a une interface graphique et une ligne de commande.

Un outil open source pour rechercher et remplacer du texte dans plusieurs fichiers.

Caractéristiques

  • Téléchargement de fichier unique - fnr.exe (127 Ko)
  • Remplacer le texte dans plusieurs fichiers à l'aide de l'application Windows ou via la ligne de commande
  • Rechercher uniquement pour voir où se trouvent les correspondances
  • Recherche sensible à la casse
  • Recherche de fichiers dans un répertoire ou des sous-répertoires récurrents
  • Expressions régulières
  • Rechercher et remplacer du texte multiligne
  • Générer un bouton de ligne de commande pour créer un texte de ligne de commande à mettre dans un fichier batch
  • Aide de la ligne de commande
  • Tests unitaires du moteur Rechercher/Remplacer

Affichage des options de ligne de commande

On dirait que vous pouvez utiliser regex avec FINDSTR

findstr permet de rechercher du texte (comme spécifié avec le motif dans le fichier nom-fichier. Si nom-fichier contient des caractères génériques (* ou ?), il recherche dans tous les fichiers qui correspondent. L'option /S recherche dans le répertoire courant ainsi que dans ses sous-répertoires. Si pattern contient des espaces, il doit être spécifié comme /C:"un texte à rechercher". Afin de transformer pattern en expressions régulières, l'option /R doit être utilisée. L'option /I recherche insensible à la casse.

À partir de l'aide de FindStr ( Findstr /? ):

/R - Utilise les chaînes de recherche comme expressions régulières.

Je suis un peu en retard pour la fête, mais JREPL.BAT est un utilitaire d'expression régulière basé sur un script JScript/batch hybride qui s'exécute nativement sur n'importe quelle machine Windows à partir de XP.

Une documentation complète est intégrée au script, accessible via JREPL /? , ou utilisez JREPL /?? pour la sortie paginée.

JREPL utilise l'expression régulière ECMA standard fournie avec JScript. L'expression régulière ECMA n'est pas aussi puissante que l'expression régulière .NET disponible pour powershell, mais elle est toujours très bonne. Et je pense que l'utilisateur moyen trouvera cet utilitaire plus facile à utiliser que powershell.

Les options JREPL intégrées fournissent déjà beaucoup de puissance inhérente, mais la possibilité d'injecter du JScript fourni par l'utilisateur ouvre vraiment des possibilités étonnantes.

J'ai développé le script car mon lieu de travail ne permet pas le téléchargement de fichiers exe non standard, mais n'a aucune restriction sur l'écriture de scripts batch ou JScript :-)


Voir la vidéo: 29 - Rechercher et remplacer avec Excel (Octobre 2021).