Fügen Sie vor dem Großbuchstaben Leerzeichen ein

8

Ich habe eine Saite:

AddData
TestSomething
TellMeWhoYouAre

und so weiter. Ich möchte vor Großbuchstaben Leerzeichen einfügen. Wie kann ich es tun?

HeroFromEarth
quelle
7
Was möchten Sie tun, wenn aufeinanderfolgende Großbuchstaben vorhanden sind? BeispielIClimbALadder
Glenn Jackman
1
Eigentlich habe ich eine Zeichenfolge wie ReadFileFromCDDriveund @Kusalanandas Lösung funktioniert großartig.
HeroFromEarth

Antworten:

16

Verwenden sedund vorausgesetzt, Sie möchten kein Leerzeichen vor dem Wort:

$ sed 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/g' file.in
Add Data
Test Something
Tell Me Who You Are

Bei der Ersetzung wird nach einem Großbuchstaben gesucht, der unmittelbar auf ein anderes Nicht-Leerzeichen folgt, und ein Leerzeichen zwischen den beiden eingefügt.

WeAreATeamDies ergibt für Zeichenfolgen mit mehr als einem aufeinanderfolgenden Großbuchstaben Folgendes We Are ATeam. Führen Sie die Substitution ein zweites Mal aus, um dies zu sortieren:

$ sed -e 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/g' \
      -e 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/g' file.in
Kusalananda
quelle
1
Diese Antwort fügt vor einem Großbuchstaben kein Leerzeichen ein, wenn vor einem Großbuchstaben steht. Warum so schreiben, wenn das OP keine solche Einschränkung auferlegt hat?
LarsH
@LarsH Es wurde behoben.
Kusalananda
Nein, hast du nicht. Sie können keine überlappenden Übereinstimmungen mit einem regulären Ausdruck haben, auch nicht mit einer gFlagge. Versuchen Sie echo ThisIsATest | sed 's/\(.\)\([[:upper:]]\)/\1 \2/g'(Ihr Befehl) herauszufinden, warum es nicht funktioniert.
Wildcard
@ Wildcard Wonky, funktioniert aber. Haben Sie einen besseren Vorschlag für die Verwendung von BREs?
Kusalananda
Es ist nicht wirklich sagen , keinen Platz zu Beginn, so s/[A-Z]/ \0/gganz zufrieden stellend ist ... `s / [AZ] / \ 0 / g; s / ^ //‘ , wenn Sie wirklich interessieren.
Michael Homer
12

Perl, mit regulären Ausdrücken von lookbehind und lookahead mit der Breite Null:

$ perl -pe 's/(?<=\w)(?=[A-Z])/ /g'  file.in 

Tell Me Who You Are                    ## TellMeWhoYouAre
I Am A Regular Expression User         ## IAmARegulaExpressionUser

Diese Version trennt auch aufeinanderfolgende Großbuchstaben.

JJoao
quelle
1
Dies wird ReadFileFromUSBDrivezu, Read File From U S B Drivewährend das OP wollte Read File From USB Drive.
Kusalananda
1
@Kusalananda, danke, dass du darauf hingewiesen hast. (Ich fürchte, ich sehe das nicht in der Frage). In realen Situationen (Programmierverständnis, Erweiterung von ID-Wörtern und CamelCase-Varianten) wird häufig ein grundlegendes Kriterium verwendet (entweder in Großbuchstaben oder umgekehrt) und es gibt ein Wörterbuch mit Ausnahmen.
JJoao
1
Entschuldigung, das hat das OP in den Kommentaren zu meiner Antwort geschrieben. Ich stimme zu, es ist schwierig, dies ohne eine Wortliste zu tun.
Kusalananda
2
sed -r -e "s/([^A-Z])([A-Z])/\1 \2/g"

Fügen Sie Leerzeichen zwischen einem Buchstaben, der kein Großbuchstabe ist, und einem Buchstaben, der ein Großbuchstabe ist, hinzu

ka3ak
quelle
Kürze ist akzeptabel, aber ausführlichere Erklärungen sind besser. . Was ist außerdem der Sinn von [^^]("kein Caret ( ^)")?
Kusalananda
@Kusalananda Du hast recht. Das Leerzeichen wird nicht zwischen ^ und Add in "^ AddData" eingefügt. Ich habe meine Antwort bearbeitet.
Ka3ak
0

Python-Lösung:

#!/usr/bin/env python
from __future__ import print_function
import sys

with open(sys.argv[1]) as f:
    for line in f:
        for char in line:
            if char.isupper():
               print(" "+char,end="")
            else:
               print(char,end="")

Testlauf:

$ ./add_space_to_upper.py input.txt                        
 Add Data
 Test Something
 Tell Me Who You Are
Sergiy Kolodyazhnyy
quelle
Sie wollen print(line[0], end="")gefolgt von for char in line[1:]:Drucken , dass unerwünschte Leerzeichen am Anfang jeder Ausgangsleitung zu vermeiden.
Paul Evans