1
votes

Comment remplacer une valeur de demande après un modèle spécifique dans un fichier texte?

Solaris, VERSION: 11.10.0, REV = 2005.01.21.15.53
J'ai un fichier test.txt qui contient des valeurs comme ci-dessous:

sed 's/(<AccountNumber>)\+[0-2,4-9]*$/\1 33333333/' test.txt
sed 's/(<BranchNumber>)\+[0-2,4-9]*$/\1 33333/' test.txt

Toutes les informations sont dans une ligne et nous avons plusieurs lignes comme ci-dessus également d'autres balises sont disponibles .

Il contient également d'autres valeurs de balises. De plus, si les valeurs de la balise contiennent une combinaison "333", je ne veux pas les remplacer.

Je veux utiliser la commande sed pour remplacer la valeur de la balise par 33333 et après le remplacement, je veux enregistrer le informations mises à jour dans le même fichier.
La sortie doit être:

 <Info>
     <AccountNumber>33333333</AccountNumber>
     <BranchNumber>33333</BranchNumber>
     <TransitNumber>3333333</TransitNumber>
     <NameAndCity>333 33333</NameAndCity>
     <OwnerFullName>3333 33333</OwnerFullName>
  </Info>

Je suis nouveau dans le script shell et je ne suis pas exactement capable d'écrire le modèle correspondant.

Voici ce que j'ai implémenté jusqu'ici aux deux premières valeurs de balise mais cela ne fonctionne pas:

 <Info>
     <AccountNumber>23456789</AccountNumber>
     <BranchNumber>004</BranchNumber>
     <TransitNumber>01646</TransitNumber>
     <NameAndCity>XYZ Bank</NameAndCity>
     <OwnerFullName>ABC XYZ</OwnerFullName>
  </Info>

Toute aide sera appréciée.


4 commentaires

Les balises réelles sont: 2345678 234


merci Tiw, mis à jour


Ahh ... Je pensais que vous ne vouliez remplacer que deux balises, mais après modification, je vois que vous voulez remplacer les valeurs dans toutes les balises?


Solaris, VERSION: 11.10.0, REV = 2005.01.21.15.53


3 Réponses :


1
votes

Essayez ceci:

perl -pe 'unless (/333/) {s#<AccountNumber>[0-9]*</AccountNumber>#<AccountNumber>333333333</AccountNumber>#;s#<BranchNumber>[0-9]*</BranchNumber>#<BranchNumber>33333</BranchNumber>#;}' test.txt

Par exemple:

perl -pe 's#<AccountNumber>[0-9]*</AccountNumber>#<AccountNumber>333333333</AccountNumber>#' test.txt

Une manière très simple, si vous testez ok et que vous voulez changer le fichier en place , ajoutez le commutateur -i .

Je n'ai pas Solaris à tester, donc je ne peux pas en être sûr.

Essayez ce simple perl pour voir si cela fonctionne:

$ sed -e '/333/!{' -e 's#<AccountNumber>[0-9]*</AccountNumber>#<AccountNumber>333333333</AccountNumber>#;s#<BranchNumber>[0-9]*</BranchNumber>#<BranchNumber>33333</BranchNumber>#;}'  test.txt
 <Info>
     <AccountNumber>333333333</AccountNumber>
     <BranchNumber>33333</BranchNumber>
     <TransitNumber>01646</TransitNumber>
     <NameAndCity>XYZ Bank</NameAndCity>
     <OwnerFullName>ABC XYZ</OwnerFullName>
  </Info>

Si cela fonctionne, nous pouvons en ajouter d'autres. p>

Donc, pour votre logique écrite pour la première fois dans la question, elle devrait être comme ceci:

sed -e '/333/!{' -e 's#<AccountNumber>[0-9]*</AccountNumber>#<AccountNumber>333333333</AccountNumber>#;s#<BranchNumber>[0-9]*</BranchNumber>#<BranchNumber>33333</BranchNumber>#;}'

Vous pouvez ajouter d'autres sous-positions vous-même. le # consiste à remplacer le / habituel des s , un moyen plus simple d'éviter d'échapper le / dans les balises fermées (IE s # de # à #; ).
C'est assez simple donc je pense que vous n'aurez aucune difficulté :)
Ajoutez le commutateur -i pour changer en place, comme ceci: perl -i -pe '... .


0 commentaires

1
votes
$ perl -pe 's#<([^>]+)>(?:(?!333).)*</\1>#<\1>333333333<\1>#;s#<([^>]+)>333 .*#<\1>333 3333</\1>#' -i file.txt
<Info>
    <AccountNumber>333333333<AccountNumber>
    <BranchNumber>333333333<BranchNumber>
    <TransitNumber>333333333<TransitNumber>
    <NameAndCity>333333333<NameAndCity>
    <OwnerFullName>333333333<OwnerFullName>
</Info>
<Info>
    <AccountNumber>333333333<AccountNumber>
    <BranchNumber>333333333<BranchNumber>
    <TransitNumber>333333333<TransitNumber>
    <NameAndCity>333 3333</NameAndCity>
    <OwnerFullName>333333333<OwnerFullName>
</Info>

6 commentaires

$ sed -r '/.*333 /! s # ^ (\ s * <[^>] +>). * (] +>) $ # \ 133333 \ 2 #; s | ^ ( \ s * <[^>] +> 333). * (] +>) $ | \ 133333 \ 2 | ' test.txt sed: option illégale - r @Bayou


@minkuJha Ah, je vois man sed . Dans gnu-sed, l'option -r active l'expression régulière étendue. Selon man regex , vous avez déjà de retour les références. Pourrait-il essayer sans l'option -r à la place?


J'ai aussi essayé avec -r mais même résultat: $ sed -r '/.*333 /!s#^(\s*<[^>letter+>).*(letter+>)$ # \ 133333 \ 2 #; s | ^ (\ s * <[^>] +> 333). * (] +>) $ | \ 133333 \ 2 | ' test.txt sed: option illégale - r @Bayou


C'est correct @Tiw, Solaris n'a pas gnu-sed


@minkuJha Vous n'avez pas supprimé l'option -r entre sed et le regex. Vous obtiendrez quelque chose comme sed "" .


$ sed '/.*333 /!s#^(\s*<[^> +>).*( Often+>)$#\133333\2#;s|^(\s * <[^>] +> 333). * (] +>) $ | \ 133333 \ 2 | ' test.txt sed: commande brouillée: /.*333 /!s#^(\s*<[^> +>).*( +>)$#\133333\2#;s | ^ (\ s * <[^>] +> 333). * (] +>) $ | \ 133333 \ 2 | @Bayou



1
votes

Publication avec tous les détails corrects pour les futurs utilisateurs:

perl -i -pe 'unless (/333/) {s#<AccountNumber>[0-9]*</AccountNumber>#<AccountNumber>33333333</AccountNumber>#;
        s#<BranchNumber>[0-9]*</BranchNumber>#<BranchNumber>33333</BranchNumber>#;
        s#<TransitNumber>[0-9]*</TransitNumber>#<TransitNumber>3333333</TransitNumber>#;
        s#<NameAndCity>[A-Za-z\ \-\+]*</NameAndCity>#<NameAndCity>333 33333</NameAndCity>#;
        s#<OwnerFullName>[A-Za-z/\/\ \+]*</OwnerFullName>#<OwnerFullName>3333 33333</OwnerFullName>#;}' test.txt 

Ci-dessus remplacera toute la valeur de la balise par 333333333 même si ce n'est pas les balises AccountNumber, BranchNumber..etc, elle remplacera les autres valeurs de balises ainsi que . également NameAndCity et OwnerFullName sont alphanumériques, nous devons donc ajouter Regex avec alphanumérique / spécial / espace pour ceux-ci. Voici la réponse:

perl -pe 's#<([^>]+)>(?:(?!333).)*</\1>#<\1>333333333<\1>#;s#<([^>]+)>333 .*#<\1>333 3333</\1>#' -i file.txt


1 commentaires

@Tiw, pouvez-vous accepter ma réponse pour référence future. trouvé quelques problèmes, donc ajouté le modifié avec tous les détails.