Mój plik tekstowy wygląda następująco:
This is one
sentence that is broken.
However this is a good one.
And this
one is
somehow, broken into
many.
Chcę usunąć końcowy znak nowej linii dla każdej linii, po której następuje linia rozpoczynająca się od małej litery.
Powinno to być:
This is one sentence that is broken.
However this is a good one.
And this one is somehow, broken into many.
Jak mogę to zrobić?
Edycja: Jest tu kilka naprawdę dobrych odpowiedzi, ale zdecydowałem się zaakceptować pierwszą, która zadziałała i była najwcześniejsza. Dziękuję bardzo wszystkim!
Odpowiedzi:
próbować
gdzie
$NF !~ /\.$/
dopasuj linię, w której ostatni element nie kończy się kropką,{ printf "%s ",$0
wydrukuj ten wiersz ze spacją i bez podawania wiersza,next ; }
pobierz następną linię,{print;}
i wydrukuj to.Jestem pewien, że będzie
sed
opcja.Uwaga: będzie to działać z linią kończącą się kropką, jednak warunek w zdaniach rozpoczynających się od dużej litery nie zostanie scalony. Zobacz odpowiedź Stéphane'a Chazelasa.
źródło
awk 'ORS=$NF~/\.$/?"\n":" "'
Z
awk
:Oznacza to, że nie dołączaj separatora rekordów do każdej linii (pusty ORS). Ale wstaw separator rekordów przed bieżącym wierszem, jeśli nie w pierwszym wierszu, a bieżący wiersz nie zaczyna się od małej litery. W przeciwnym razie wstaw znak spacji zamiast pierwszego wiersza.
źródło
And thisone issomehow, broken intomany.
nie wiem,awk
ale należy połączyć linie<space>
opróczRS
? Czy ten błąd użytkownika?W perlu:
Technicznie rzecz biorąc, chciałeś zastąpić „newline, po którym małymi literami”, „spacją i małą literą”, co robi rdzeń powyższego skryptu perl:
input
.input
zmienną, aby była wynikiem operacji wyszukiwania i zamiany.źródło
perl -0777 -pe 's/\n([a-z])/ $1/g'
i podobnie można to zrobić za pomocą GNU sed jakosed -zE 's/\n([a-z])/ \1/g'
(zakładając, że dane wejściowe nie mają znaków zerowych)perl -Mopen=locale -0777 -pe 's/\n(?=[[:lower:]])/ /g'
aby nie ograniczać się do liter ASCII.Ze
sed
można użyćN;P;D
cyklu (tak aby zawsze mieć dwie linie w przestrzeni wzorca, a jeśli pierwszy znak po znaku nowej linii jest małe litery następnie zastąpić przełamane spacją) orazt
Est - w ten sposób po każdyms
ubstitution uruchomieniu cyklu:źródło
N;P;D
t
P;D
Korzystanie
sed
ifmt
:Skrypt sed wstawia nowy wiersz przed każdym wierszem rozpoczynającym się od dużej litery (z wyjątkiem pierwszego wiersza wprowadzania).
sed
Dane wyjściowe są następnie przesyłane wfmt
celu sformatowania powstałych akapitów.Alternatywnie użyj,
par
jeśli masz zainstalowany. To kolejny formatowanie akapitów, ale o wiele bardziej wydajny niżfmt
, z wieloma dodatkowymi funkcjami i opcjami.Zauważ, że pomiędzy każdym akapitem będzie pusta linia. Akapity powinny być oddzielone od siebie co najmniej jedną pustą linią. Bez pustych wierszy cała próbka wejściowa jest sformatowana jako pojedynczy akapit z wieloma zdaniami, np .:
Jeśli musisz usunąć puste linie po
sed
ponownym sformatowaniu, po prostu przeciągnij je ponownie - ale spowoduje to usunięcie WSZYSTKICH pustych linii, w tym również tych, które mogły znajdować się w oryginalnym pliku wejściowym. na przykładźródło
Innym sposobem na to jest:
gdzie:
$\
=>ORS
,$/
=>IRS
=\n
,$"
=space
źródło
Python 3
To jest to samo wyrażenie regularne / podstawienie co odpowiedź Jeffa
źródło