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

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

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 balise. De plus, si les valeurs de 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 les 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 pour le faire correspondre.

Voici ce que j'ai mis en œuvre jusqu'à présent pour les deux premières valeurs de balise mais cela ne fonctionne pas:

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

Toute aide serait appréciée .

1
minku Jha 26 janv. 2019 à 16:40

3 réponses

Meilleure réponse

Essaye ça:

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

Par exemple:

$ 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>

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 être sûr.

Essayez ce simple perl pour voir si cela fonctionne:

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

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

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

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

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

1
Tiw 26 janv. 2019 à 15:48
$ cat file.txt 
<Info>
    <AccountNumber>23456789</AccountNumber>
    <BranchNumber>004</BranchNumber>
    <TransitNumber>01646</TransitNumber>
    <NameAndCity>XYZ Bank</NameAndCity>
    <OwnerFullName>ABC XYZ</OwnerFullName>
</Info>
<Info>
    <AccountNumber>23456789</AccountNumber>
    <BranchNumber>004</BranchNumber>
    <TransitNumber>01646</TransitNumber>
    <NameAndCity>333 Bank</NameAndCity>
    <OwnerFullName>ABC XYZ</OwnerFullName>
</Info>

$ sed -r '/.*333 /!s#^(\s*<[^>]+>).*(</[^>]+>)$#\133333\2#;s|^(\s*<[^>]+>333 ).*(</[^>]+>)$|\133333\2|' file.txt
<Info>
    <AccountNumber>33333</AccountNumber>
    <BranchNumber>33333</BranchNumber>
    <TransitNumber>33333</TransitNumber>
    <NameAndCity>33333</NameAndCity>
    <OwnerFullName>33333</OwnerFullName>
</Info>
<Info>
    <AccountNumber>33333</AccountNumber>
    <BranchNumber>33333</BranchNumber>
    <TransitNumber>33333</TransitNumber>
    <NameAndCity>333 33333</NameAndCity>
    <OwnerFullName>33333</OwnerFullName>
</Info>

Annulez d'abord les chaînes contenant ">333 " avec /.*333 /!. Ces chaînes seront affectées par la deuxième expression régulière s#^(\s*<[^>]+>).*(</[^>]+>)$#\133333\2#;. Les chaînes contenant ">333 " seront modifiées conformément à s|^(\s*<[^>]+>333 ).*(</[^>]+>)$|\133333\2|.

Ajoutez l'option -i à sed pour appliquer les modifications.

ÉDITER:

Comme @Tiw l'a commenté, il est préférable d'utiliser perl au lieu de sed:

$ 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>

Remarque: l'option -i applique les modifications au fichier.

1
Bayou 26 janv. 2019 à 15:38

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

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

Ci-dessus remplacera toute la valeur de la balise par 333333333 même si ce n'est pas des balises AccountNumber, BranchNumber..etc, elle remplacera également d'autres valeurs de balises. é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 -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 
1
minku Jha 27 janv. 2019 à 07:33