2009-03-25 13 views
1

J'ai un problème de substitution. J'ai un fichier avec 1 ligne de caractères aléatoires avec des parenthèses "{}" autour de 1 caractère. Je veux bouger avec ces parenthèses sur le caractère précédent ou sur le suivant. (Je sais comment le faire si la ligne de personnage est immobile, non changeante.) Mais je me demande comment le faire quand je ne connais pas ces caractères et je ne sais pas où ces parenthèses sont.Unix - substitution

Par exemple: "ABC123 {X} CBA321" ==> "ABC12 {3} XCBA321" ou "ABC123X {C} BA321"

Je voudrais utiliser awk ou sed, certains regex, peut-être. ..

Répondre

5

Déplacer vers l'arrière d'un caractère:

sed -e 's/\(.\){\(.\)}/{\1}\2/g' file 

avancer d'un caractère:

sed -e 's/{\(.\)}\(.\)/\1{\2}/g' file 

Pour modifier le fichier en pl ace, utilisez le drapeau -i:

sed -i -e 's/\(.\){\(.\)}/{\1}\2/g' file 
sed -i -e 's/{\(.\)}\(.\)/\1{\2}/g' file 

Le premier exemple fonctionne en faisant correspondre un caractère suivi d'un caractère entouré de {}. Sans grouper, c'est: .{.} Nous ajoutons un groupement pour que nous puissions mettre les deux caractères dans la sortie. Au lieu d'entourer le deuxième caractère avec {} avec entourer le premier caractère. Ceci est {\1}\2.

Le deuxième exemple fonctionne de manière similaire, mais correspond à {.}. en premier puis sort \1{\2}.

+0

Pas upvote jusqu'à ce que vous vous débarrasser du chat étranger! –

+0

@Tomblin, j'ai utilisé cat comme exemple pour montrer que les données pouvaient être canalisées. @ashawley montre un meilleur exemple de cela. – strager

+0

Nice one, strager –

3

Cela déplacera les crochets au caractère précédent:

sed -e 's/\(.\){\(.\)}/{\1}\2/g' <in_file> out_file 

Cela déplacera les crochets au caractère suivant:

sed -e 's/{\(.\)}\(.\)/\1{\2}/g' <in_file> out_file 
+0

Wow, je vous ai battu de quatre secondes. Et nous avons exactement la même expression rationnelle. xD – strager

+0

+1 pour vous deux. J'étais incapable de décider. ;-) – Tomalak

+0

@ strager, davr: Vous avez tous les deux des regexps plus courtes, mais je ne pense pas que le modificateur "g" soit inutile. – ashawley

1

Voici un petit exemple.

$ echo "ABC123{X}CBA321" | sed -e 's/\(.\){\(.\)}\(.\)/{\1}\2\3/' 
ABC12{3}XCBA321 
$ echo "ABC123{X}CBA321" | sed -e 's/\(.\){\(.\)}\(.\)/\1\2{\3}/' 
ABC123X{C}BA321 

Voici comment éditer le fichier en place avec sed.

$ sed -i -e 's/\(.\){\(.\)}\(.\)/{\1}\2\3/' file 
$ sed -i -e 's/\(.\){\(.\)}\(.\)/\1\2{\3}/' file 
0

J'ai essayé en perl. cela déplace le support au caractère précédent

my $a="ABC123{X}CBA321"; 

if ($a =~ /(.)\{(.)\}/) 
     { 
       print "$`"."{$1}"; 
       print "$2"; 
       print "$'"; 
     } 

REMARQUE: `$ est une chaîne avant le match & $ » est une chaîne après un match

+0

Je me suis échappé, mais je ne sais pas pourquoi ce n'était pas reflété dans mon post.Merci –