tags:

views:

145

answers:

4

Hi, i have problem with substitution. I have a file with 1 line of random characters with brackets "{}" around 1 character. I want to move with these brackets on the previous character or on the next one. (I know how to do it if the line of character is still, non-changing.) But I wonder how to do it when I don't know these chars and I don't know where these brackets are.

For Example: " ABC123{X}CBA321 " ==> " ABC12{3}XCBA321 " or " ABC123X{C}BA321 "

I would like to use awk or sed, some regex, maybe...

+5  A: 

Move backward one character:

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

Move forward one character:

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

To modify the file in-place, use the -i flag:

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

The first example works by matching any character followed by a character surrounded by {}. Without grouping, this is: .{.} We add grouping so we can put the two characters in the output. Instead of surrounding the second character with {} with surround the first character. This is {\1}\2.

The second example works similarly, but matches {.}. first then outputs \1{\2}.

strager
No upvote until you get rid of the extraneous cat!
Paul Tomblin
@Tomblin, I used cat as an example to show the data could be piped. @ashawley shows a better example of this.
strager
Nice one , strager
TGV
+3  A: 

This will move the brackets to the previous character:

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

This will move the brackets to the next character:

sed -e 's/{\(.\)}\(.\)/\1{\2}/g' < in_file > out_file
davr
Wow, I beat you by four seconds. And we have the exact same regexp. xD
strager
+1 for both of you. I was unable to decide. ;-)
Tomalak
@strager,davr: You both had shorter regexps, but I don't think the "g" modifier is unnecessary.
ashawley
Awesome. You guys are pretty fast :-)
TGV
+1  A: 

Here's a small example.

$ 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

Here's how to edit the file in place with sed.

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

I tried in perl. this will move the bracket to the previous character

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

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

NOTE: $` is string before the match & $' is string after match

TGV
I did escape , but not sure why it was not reflected in my post.Thank you
TGV