Ich habe ein Textdokument, das eine Menge Text enthält, der nach jedem Buchstaben ein zusätzliches Leerzeichen enthält!
Beispiel:
T h e b o o k a l s o h a s a n a n a l y t i c a l p u r p o s e w h i c h i s m o r e i m p o r t a n t…
Visuell:
T␣h␣e␣b␣␣o␣o␣k␣a␣␣l␣s␣o␣h␣␣a␣s␣a␣␣n␣a␣␣n␣a␣l␣y␣t␣i ␣c␣a␣l␣p␣␣u␣r␣p␣o␣s␣e␣w␣␣h␣i␣c␣h␣i␣␣s␣m␣␣o␣r␣e␣i␣ m␣p␣o␣r␣t␣a␣n␣t…
Beachten Sie, dass es ein Extra gibt nach jedem Buchstaben Leerzeichen steht, sodass zwischen aufeinanderfolgenden Wörtern zwei Leerzeichen stehen.
Gibt es einen Weg, den ich bekommen kann awk
odersed
die zusätzlichen Leerzeichen zu löschen? (Leider ist dieses Textdokument sehr umfangreich und die manuelle Bearbeitung würde sehr viel Zeit in Anspruch nehmen.)
Ich schätze, dass dies wahrscheinlich ein viel komplexeres Problem ist, das nur mit einem einfachen Bash-Skript gelöst werden kann, da es auch eine Art Texterkennung geben muss.
Wie kann ich dieses Problem angehen?
text-processing
sed
awk
scripting
Loowen
quelle
quelle
echo 't h i s i s a n e x a m p l e' | sed 's/ //g'
echo 'T h i s ; i s .a n 9 8 e x a m p l e' | perl -pe 's/[a-z]\K (?=[a-z])//ig'
Antworten:
Der folgende reguläre Ausdruck entfernt das erste Leerzeichen in einer beliebigen Folge von Leerzeichen. Das sollte den Job machen.
Also so etwas wie:
... ersetzt infile.txt durch eine "feste" Version.
quelle
perl -pie
wie Ihre Bearbeitung zeigt. Was ist der Grund dafür? Das -pie hat immer gut für mich funktioniert und ist eine großartige Gedächtnisstütze. Hat sich das Verhalten von -i dahingehend geändert, dass alles, was folgt, als Erweiterung behandelt wird und nicht nur die Dinge, die mit einem Punkt beginnen? Es wäre seltsam für sie, etwas so Idiomatisches zu brechen.-i
. Andererseits habe ich es bisher nur auf Linux-Rechnern verwendet und seit einigen Jahren nichts mehr darüber gewusst. Daher kann ich nicht über sein älteres Verhalten sprechen. Auf meinem Rechner aber dies:perl -pie 's/a/b/' f
, erzeugt einen Fehler:Can't open perl script "s/o/A/": No such file or directory
. Whileperl -i -pe 's/o/A/' f
funktioniert wie erwartet. Also ja, dase
wird als Backup-Erweiterung genommen.Verwenden Sie
wordsegment
ein NLP-Paket für die reine Python-Wortsegmentierung:quelle
Basierend auf der Tatsache, dass die Eingabe doppelte Leerzeichen zwischen Wörtern enthält, gibt es eine viel einfachere Lösung. Sie ändern einfach die doppelten Leerzeichen in ein unbenutztes Zeichen, entfernen die Leerzeichen und ändern das unbenutzte Zeichen wieder in ein Leerzeichen:
... Ausgänge:
quelle
sed -e "s/\([^ ]\) /\1/g"
Perl zur Rettung!
Sie benötigen ein Wörterbuch, dh eine Datei mit einem Wort pro Zeile. Auf meinem System existiert es als
/var/lib/dict/words
, ich habe auch ähnliche Dateien wie/usr/share/dict/british
etc. gesehen.Zunächst erinnern Sie sich an alle Wörter aus dem Wörterbuch. Anschließend lesen Sie die Eingabe zeilenweise und versuchen, einem Wort Zeichen hinzuzufügen. Wenn es möglich ist, erinnern Sie sich an das Wort und versuchen, den Rest der Zeile zu analysieren. Wenn Sie das Zeilenende erreichen, geben Sie die Zeile aus.
Für Ihre Eingabe generiert es 4092 mögliche Messwerte auf meinem System.
quelle
a cat a log
a c a t a l o g
Hinweis: Diese Antwort (wie auch einige andere hier) basiert auf einer früheren Version der Frage, bei der Wörter nicht getrennt wurden. Die neuere Version kann trivial beantwortet werden .
Bei einer Eingabe wie:
Du könntest es versuchen:
Es wird von links nach rechts abgearbeitet und findet ein langes Wort nach dem anderen.
Natürlich ist es hier nicht die beste Wortauswahl, da dieser Satz keinen Sinn ergibt. Um jedoch den richtigen Satz zu finden, benötigen Sie Tools, die die Grammatik oder Bedeutung des Textes oder zumindest einige statistische Informationen verstehen Informationen darüber, welche Wörter wahrscheinlich zusammen gefunden werden, um die wahrscheinlichste Wortgruppe zu finden. Die Lösung scheint eine spezialisierte Bibliothek zu sein, wie sie Lynn gefunden hat
quelle
Ähnlich wie Dewi Morgans Version, aber mit sed:
quelle
sed
nur GNU und das entspricht nicht Dewi's. Das Standardäquivalentsed
zu Dewi's wäresed 's/ \( *\)/\1/g'
Obwohl es mit einem Perl-Einzeiler gemacht werden könnte (und sollte), wäre ein kleiner C-Parser auch sehr schnell und ist auch sehr klein (und hoffentlich sehr korrekt):
Kompiliert mit
(Programm ist etwas kleiner als 9kb)
Verwenden Sie in einem Rohr wie zB:
quelle
Ich habe es versucht und es scheint zu funktionieren:
Der
sed
Befehl erfasst zwei Gruppen und gibt nur die erste zurück.quelle
In c ++ würde ich dies tun:
Ändert den Inhalt der Testtextdatei in dieselbe Zeichenfolge, wobei jedoch Leerzeichen zwischen den Buchstaben entfernt werden. (Um genau zu sein, muss zwischen jedem Buchstaben ein Leerzeichen eingefügt werden.)
quelle
quelle