J'ai plusieurs fichiers avec du texte qui doit être remplacé. Le texte commence et se termine avec le même motif à chaque fois, mais le contenu entre les motifs est variable. Les motifs peuvent apparaître au milieu de lignes et le contenu qui les sépare s'étend souvent sur plusieurs lignes.
Il n'y aura qu'une seule occurrence du motif de début et de fin dans chaque fichier.
J'ai besoin d'une méthode de ligne de commande pour remplacer le texte entre les modèles, y compris les modèles eux-mêmes. La sortie dans un nouveau fichier ou la modification sur place convient.
Une commande qui opère sur un seul fichier fonctionnera, car je peux parcourir les fichiers et appliquer la commande moi-même. J'ai essayé une solution sed
mais je ne pouvais que remplacer des lignes entières.
Un exemple de texte serait:
Cable Type ID:135, Installation ID:62, Alpha Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Beta Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Phase Conductor Size:
45mm, Security: Security-Start Bs86gKI-734Lw#32_nP/5589Zfb8Wj-
sW93j9b Security-End, Location ID:889, Protective Earth Size:
67mm, Protective Earth Max Current (A): 4, Overload Time...
Le modèle de départ est Security-Start
et le modèle de fin est Security-End
. Je souhaite remplacer les modèles et tout le reste par Word REDACTED
.
Je voudrais que la sortie soit:
Cable Type ID:135, Installation ID:62, Alpha Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Beta Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Phase Conductor Size:
45mm, Security: REDACTED, Location ID:889, Protective Earth Size:
67mm, Protective Earth Max Current (A): 4, Overload Time...
Veuillez noter que le texte entre les deux modèles peut être si long qu'il couvre plusieurs lignes, il est assez aléatoire. Ce n'est pas clair dans l'exemple ci-dessus
Toute langue disponible par défaut sur un système Ubuntu conviendra. Mes premières pensées sont 'sed' ou 'awk', mais tout ce avec quoi vous serez à l'aise ira bien.
Il devrait fonctionner pour vous:
sed -e '/Security-Start/{ N; s/Security-Start.*Security-End/REDACTED/ }'
/Security-Start/
recherche "Security-Start"s/Security-Start.*Security-End/REDACTED/
au résultat final.Pour plus de deux lignes, utilisez celle-ci:
sed -n '1h; 1!H; ${ g; s/Security-Start.*Security-End/REDACTED/p }'
Lire ici
Si les fichiers ne sont pas trop volumineux, vous pouvez utiliser Perl en mode Slurp:
$ Perl -0777 -pe 's/Security-Start.*Security-End/REDACTED/s' file
Cable Type ID:135, Installation ID:62, Alpha Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Beta Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Phase Conductor Size:
45mm, Security: REDACTED, Location ID:889, Protective Earth Size:
67mm, Protective Earth Max Current (A): 4, Overload Time...
Le paramètre de ligne de commande -0777
désactive efficacement le séparateur d’enregistrements de sorte que le fichier entier soit insufflé. Le modificateur regex s
force Perl à inclure les caractères de nouvelle ligne dans .
, ce qui permet à l'expression de correspondre sur toutes les lignes.
Alternativement, avec une boucle sed:
$ sed '/Security-Start/ {:a; $!N; s/Security-Start.*Security-End/REDACTED/; t; ba}' file
Cable Type ID:135, Installation ID:62, Alpha Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Beta Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Phase Conductor Size:
45mm, Security: REDACTED, Location ID:889, Protective Earth Size:
67mm, Protective Earth Max Current (A): 4, Overload Time...
Avec GNU sed, vous pouvez remplacer t; ba
(branche en cas de remplacement réussi; (sinon) branchez-le à :a
) par Ta
(branchez-vous à :a
sur n remplacement réussi).
Une approche plus manuelle consisterait à remplacer tous les caractères de nouvelle ligne dans le fichier d'entrée par des valeurs NULL. Utilisez une expression rationnelle Perl
non-gloutonne pour effectuer le remplacement, puis réinstallez les nouvelles lignes:
$ tr '\n' '\0' < file |
Perl -pe 's/Security-Start.*?Security-End/Security: REDACTED/g' |
tr '\0' '\n'
Cable Type ID:135, Installation ID:62, Alpha Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Beta Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Phase Conductor Size:
45mm, Security: Security: REDACTED, Location ID:889, Protective Earth Size:
67mm, Protective Earth Max Current (A): 4, Overload Time...
Voici comment vous pouvez le faire avec awk:
awk -v RS='Security-Start.*Security-End' -v ORS= '1;NR==1{printf "REDACTED"}' file