Rechercher, insert, déplacer et insert

Je veux searchr chaque logging (les loggings sont définis par des lignes vides) dans un file pour le model NAME#AAAA . Si cela correspond, insérez un # devant la ligne AGE de l'logging et déplacez cette ligne vers le haut du paragraphe. Ensuite, insérez la ligne AGE NIL à la fin:

FICHIER D'ENTRÉE:

 NAME#AAAA STD 1 SEC A AGE 5 NAME#BBBB STD 2 SEC B AGE 6 NAME#CCCC STD 3 SEC C AGE 7 NAME#AAAA STD 4 AGE 9 NAME#AAAA STD 7 SEC A AGE 12 

PRODUCTION ATTENDUE

 #AGE 5 NAME#AAAA STD 1 SEC A AGE NIL NAME#BBBB STD 2 SEC B AGE 6 NAME#CCCC STD 3 SEC C AGE 7 #AGE 9 NAME#AAAA STD 4 AGE NIL #AGE 12 NAME#AAAA STD 7 SEC A AGE NIL 

Aussi, j'ai besoin de l'inverse. Juste pour revenir au dos les changements effectués. S'il vous plaît noter que je fais tout cela sur une machine AIX.

Ceci est un cas d'utilisation parfait pour ex , l'outil de choix POSIX spécifié pour l'édition de file.

(Si vous avez déjà utilisé vi , en passant, vous êtes probablement familier avec ex puisque tout ce que vous tapez vi qui commence par un deux-points : est une command ex . ex est le prédécesseur de vi .)

 printf %s\\n 'g/NAME#AAAA/ /AGE/t- | s/^/#/ | /AGE/s/.*/AGE NIL/' x | ex input.txt 

Si vous souhaitez le tester avant de sauvegarder le file, changez le x final avant que le symbole de pipe ne soit dans %p et le file modifié ne sera pas sauvegardé, mais la version modifiée sera imprimée sur stdout . Voici donc la command de test:

 printf %s\\n 'g/NAME#AAAA/ /AGE/t- | s/^/#/ | /AGE/s/.*/AGE NIL/' %p | ex input.txt 

Explication:

printf %s\\n fournit un moyen facile de nourrir plusieurs commands à ex avec une nouvelle ligne après chaque.

g/regex/ est la command globale; il exécute les commands qui suivent (jusqu'à la nouvelle ligne suivante) sur chaque ligne qui correspond à la regex donnée.

/AGE/t- copy la ligne suivante qui correspond au motif /AGE/ à une position juste avant la ligne actuelle (qui est la ligne NAME#AAAA ). Il déplace également le slider sur la nouvelle copy de la ligne (de sorte que maintenant devient la "ligne actuelle").

| est un séparateur de commands dans ex .

s/^/#/ préfixe la ligne AGE copiée avec un hashtag. (Ou un signe dièse, selon votre dialecte.);)

La command suivante a deux parties: /AGE/ est l'adresse, ce qui fait que cette command fonctionne sur la ligne suivante qui contient ce pattern, et s/.*/AGE NIL/ remplace tout ce que cette ligne était, avec AGE NIL .

x enregistre les modifications dans le file et quitte.


Inverser les changements

Pour inverser les changements, je voudrais faire ce qui suit:

 printf %s\\n 'g/NAME#AAAA/ ?^#AGE? m /^AGE/ | s/^#// | -d' %p | ex input.txt 

Ensuite, lorsque la modification a été vérifiée, sauvegardez les modifications avec:

 printf %s\\n 'g/NAME#AAAA/ ?^#AGE? m /^AGE/ | s/^#// | -d' x | ex input.txt 

Explication:

Commande globale comme avant.

Prenez la ligne commençant par #AGE avant la ligne NAME, déplacez-la après la ligne suivante qui commence par AGE .

Supprimer le # principal.

Supprimez la ligne immédiatement précédente avec -d (qui est la ligne d'âge NIL).

Imprimez ou enregistrez les modifications.

 perl -pe 'BEGIN{$/=""} s/^(NAME#AAAA.*\n)(AGE.*?)(\n+)$/#$2\n$1AGE NIL$3/s' ex1 

très brèves explications:

 For all the registers in input | perl -p separator= one or more empty lines | BEGIN{$/=""} do: | substitute | s/ | ^(NAME AAAA.*\n)(AGE.*?)(\n+)$ | regex / | 1 2 3 | | by | /subst. ssortingng including | # $2 \n $1 AGE NIL $3 | capture groups/ | | | and print | ...from option -p 

Mettre à jour:

Est-ce possible d'avoir des variables à la place de NAME # AAAA?

 perl -pe ' BEGIN{ $/=""; $f=shift; } s/^(NAME#$f.*\n)(AGE.*?)(\n+)$/#$2\n$1AGE NIL$3/s' AAAA ex1 

Dans cette version, nous devons fournir un argument de model (Ex: "AAAA"):

  • ligne 4: récupère le premier argument de la command line ("AAAA") et le stocke dans $ f
  • ligne 5: développez $ f dans le model de rlocation.