Mam dokument tekstowy, który zawiera mnóstwo tekstu, a po każdej literze jest dodawane dodatkowe miejsce!
Przykład:
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…
Naocznie:
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…
Należy pamiętać, że istnieje dodatkowa przestrzeń po każdym liście, więc są dwie przestrzenie między kolejnymi słowami.
Czy istnieje sposób, aby uzyskać awk
lub sed
usunąć dodatkowe spacje? (Niestety ten dokument tekstowy jest bardzo obszerny i przejście go ręcznie zajęłoby bardzo dużo czasu).
Rozumiem, że jest to prawdopodobnie o wiele bardziej skomplikowany problem do rozwiązania za pomocą prostego skryptu bash, ponieważ musi istnieć także pewien rodzaj rozpoznawania tekstu.
Jak podejść do tego problemu?
text-processing
sed
awk
scripting
Lloowen
źródło
źródło
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'
Odpowiedzi:
Poniższy regex usunie pierwszą spację z dowolnego ciągu spacji. To powinno wystarczyć.
Więc coś takiego:
... zastąpi plik infile.txt wersją „naprawioną”.
źródło
perl -pie
- jak pokazuje twoja edycja. Jakie jest tego uzasadnienie? Ten kawałek zawsze działał dla mnie dobrze i jest świetnym mnemonikiem. Czy zachowanie -i zmieniło się, aby traktować wszystko jako rozszerzenie, a nie tylko te, które zaczynają się od kropki? Dziwne byłoby dla nich złamanie czegoś tak idiomatycznego.-i
. Z drugiej strony używałem go tylko na maszynach z Linuksem i nie wiedziałem o tym od ponad kilku lat, więc nie mogę mówić o jego starszym zachowaniu. Na moim komputerze jednak tak:perl -pie 's/a/b/' f
produkuje błąd:Can't open perl script "s/o/A/": No such file or directory
. Chociażperl -i -pe 's/o/A/' f
działa zgodnie z oczekiwaniami. Tak,e
jest traktowane jako rozszerzenie kopii zapasowej.Użyj
wordsegment
pakietu NLP o czystej segmentacji słów:źródło
Oparte na fakcie, że dane wejściowe zawierają podwójne spacje między słowami, istnieje znacznie prostsze rozwiązanie. Wystarczy zmienić podwójne spacje na nieużywaną postać, usunąć spacje i zmienić nieużywaną postać z powrotem na spację:
... wyjścia:
źródło
sed -e "s/\([^ ]\) /\1/g"
Perl na ratunek!
Potrzebujesz słownika, tzn. Pliku zawierającego jedno słowo w wierszu. W moim systemie istnieje, ponieważ
/var/lib/dict/words
widziałem również podobne pliki jak/usr/share/dict/british
itp.Najpierw pamiętasz wszystkie słowa ze słownika. Następnie czytasz wprowadzany wiersz po wierszu i próbujesz dodawać znaki do słowa. Jeśli to możliwe, pamiętasz słowo i próbujesz przeanalizować resztę linii. Po osiągnięciu końca linii wyprowadzasz linię.
Na podstawie twoich danych generuje 4092 możliwe odczyty w moim systemie.
źródło
a cat a log
iea c a t a l o g
Uwaga: ta odpowiedź (podobnie jak kilka innych tutaj) oparta jest na wcześniejszej wersji pytania, w którym słowa nie były rozdzielane. Na nowszą wersję można w prosty sposób odpowiedzieć .
Na wejściu takim jak:
Możesz spróbować:
Przetwarza od lewej do prawej i znajduje jedno najdłuższe słowo po drugim.
Oczywiście nie jest to najlepszy wybór słów, ponieważ zdanie to nie ma sensu, ale aby znaleźć właściwe, potrzebujesz narzędzi, które będą w stanie zrozumieć gramatykę lub znaczenie tekstu lub przynajmniej niektóre statystyki informacje o tym, jakie słowa można znaleźć razem, aby uzyskać najbardziej prawdopodobny zestaw słów. Wygląda na to, że rozwiązaniem jest specjalistyczna biblioteka znaleziona przez Lynn
źródło
Podobne do wersji Dewi Morgan, ale z sed:
źródło
sed
tylko GNU i to nie jest równoważne z Dewi. Standardowysed
odpowiednik Dewi byłbysed 's/ \( *\)/\1/g'
Chociaż można to (i należy) zrobić z liniową wersją Perla, mały parser C również byłby bardzo szybki, a także bardzo mały (i mam nadzieję, że bardzo poprawny):
Kompilowany z
(program jest nieco mniejszy niż 9 KB)
Użyj w rurze, takiej jak np .:
źródło
Próbowałem tego i wydaje się, że działa:
sed
Komenda rejestruje dwie grupy i powraca dopiero pierwszy.źródło
W c ++ zrobiłbym to:
Zmieni zawartość testowego pliku tekstowego na ten sam ciąg, ale ze spacjami między literami. (Wymagana jest spacja między każdą literą).
źródło
źródło