2009-03-25 23 views
1

Ich habe Probleme mit der Substitution. Ich habe eine Datei mit 1 Zeile zufälliger Zeichen mit Klammern "{}" um 1 Zeichen. Ich möchte mit diesen Klammern auf das vorherige Zeichen oder auf das nächste Zeichen wechseln. (Ich weiß, wie man es macht, wenn die Linie des Charakters immer noch unverändert ist.) Aber ich frage mich, wie ich es machen soll, wenn ich diese Zeichen nicht kenne und ich weiß nicht, wo diese Klammern sind.Unix - Substitution

Beispiel: "ABC123 {X} CBA321" ==> "ABC12 {3} XCBA321" oder "ABC123X {C} BA321"

Ich mag würde awk oder sed verwenden, einige regex, vielleicht. ..

Antwort

5

Zurück ein Zeichen:

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

Verschieben ein Zeichen vorwärts:

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

Um die Datei zu ändern in-pl ace, verwendet, um die Flagge -i:

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

Das erste Beispiel wirkt, indem jedes Zeichen durch ein Zeichen von {} umgeben gefolgt entsprechen. Ohne Gruppierung ist dies: .{.} Wir fügen Gruppierung hinzu, so dass wir die zwei Zeichen in die Ausgabe einfügen können. Anstatt das zweite Zeichen mit {} mit Surround umgeben das erste Zeichen. Dies ist {\1}\2.

Das zweite Beispiel funktioniert ähnlich, passt aber zuerst auf {.}. und dann auf \1{\2}.

+0

Kein upvote bis der Fremd Katze los! –

+0

@Tomblin, ich habe die Katze als Beispiel verwendet, um zu zeigen, dass die Daten weitergeleitet werden können. @ashawley zeigt ein besseres Beispiel dafür. – strager

+0

Nice one, strager –

3

Dadurch werden die Klammern zum vorherigen Zeichen bewegen:

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

Dadurch werden die Klammern zum nächsten Zeichen verschieben:

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

Wow, ich habe dich um vier Sekunden geschlagen. Und wir haben genau die gleiche Regexp. xD – strager

+0

+1 für euch beide. Ich konnte mich nicht entscheiden. ;-) – Tomalak

+0

@ strager, davr: Sie hatten beide kürzere Regexps, aber ich denke nicht, dass der Modifikator "g" unnötig ist. – ashawley

1

Hier ist ein kleines Beispiel.

$ 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 

Hier ist, wie die Datei in Ort mit sed zu bearbeiten.

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

Ich versuchte in Perl. dies wird die Klammer zum vorherigen Zeichen

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

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

HINWEIS bewegen: `$ string vor dem Spiel & $‘ ist Zeichenfolge nach Spiel

+0

Ich bin entkommen, aber ich bin mir nicht sicher, warum es in meinem Post nicht reflektiert wurde. Danke –