Yanlış yerlerde kesilen çizgileri nasıl düzeltebilirim?


11

Metin dosyam şöyle:

This is one
sentence that is broken.
However this is a good one.
And this
one is
somehow, broken into
many.

Küçük harfle başlayan bir çizgi izleyen herhangi bir satırın sondaki yeni satır karakterini kaldırmak istiyorum.

Yani bu şöyle olmalı:

This is one sentence that is broken.
However this is a good one.
And this one is somehow, broken into many.

Bunu nasıl yapabilirim?

Düzenleme: Burada gerçekten iyi cevaplar var, ama işe yarayan ve en erken ilkini kabul etmeyi seçtim . Herkese çok teşekkürler!


1
Lateks? Sorun şu ki, doğru cümle kırma kurallarını gerçekten belirtmemeniz. Her şeyi tek bir satıra cümle sonu noktalama işaretine dahil etmek mi istiyorsunuz? Peki ya uzun bir cümleniz varsa ve ekran pencerenizin kenarından kaçarsa?
jamesqf

1
Gerçekten neyi çözmeye çalıştığını merak ediyorum? Belki markdown biçimlendirmesi kullanmalısınız?
Wildcard

@JeffSchaller Hatırlatma için teşekkürler! Bir şekilde kaçırmıştım. :)

Yanıtlar:


7

Deneyin

awk '$NF !~ /\.$/ { printf "%s ",$0 ; next ; } {print;}' file

nerede

  • $NF !~ /\.$/ son öğenin bir nokta ile bitmediği eşleşme çizgisi,
  • { printf "%s ",$0 bu satırı bir boşlukla ve satır besleme olmadan yazdır,
  • next ; } sonraki satırı getir,
  • {print;} ve yazdırın.

Eminim bir sedseçenek olacak .

Not: Bu, bir nokta ile biten satırla çalışır, ancak büyük harfle başlayan cümlelerdeki koşul birleştirilmez. Stéphane Chazelas'ın cevabına bakınız.


Eğer zeki (birçok sevmiyorum)awk 'ORS=$NF~/\.$/?"\n":" "'
dave_thompson_085

10

İle awk:

awk -v ORS= '{print (NR == 1 ? "" : /^[[:lower:]]/ ? " " : RS) $0}
             END {if (NR) print RS}'

Yani, her satıra kayıt ayırıcı eklemeyin (ORS boş). Ancak , ilk satırda değilse ve geçerli satır küçük harfle başlamıyorsa, geçerli satırdan önce bir kayıt ayırıcı ekleyin . Aksi takdirde, ilk satır haricinde bir boşluk karakteri başına ekleyin.


Bunu çalıştırdığımda bazı sözcük çiftleri birleştirilir. Örneğin And thisone issomehow, broken intomany.Bilmiyorum awkama çizgiler ile beraber olmalı <space>ek olarak RS? Yoksa bu kullanıcı hatası mı?
B Katmanı

@BLayer, iyi tespit, teşekkürler. Şimdi düzeltilmelidir.
Stéphane Chazelas

Sorun değil. Gerçi 11 vekilin nereden geldiğini merak ediyor. İnsanların her zaman haklı olduğunu varsaymasını sağlamak güzel olmalı. ;)
B Katmanı

4

Perl dilinde:

#!/usr/bin/perl -w
use strict;
my $input = join("", <>);
$input =~ s/\n([a-z])/ $1/g;
print $input;

Teknik olarak, yukarıdaki perl betiğinin çekirdeğinin yaptığı, "satırsonu ve ardından küçük harf" ile "boşluk ve bu küçük harf" yerine geçmek istediniz:

  1. Bir dizenin girdisini okuma input .
  2. Güncelleyin inputDeğişkeni arama ve değiştirme işleminin sonucu olacak şekilde .
  3. Yeni değeri yazdırın.

1
İyi bir!! tek astarlı olarak çevrilmiştir perl -0777 -pe 's/\n([a-z])/ $1/g've GNU sed ile benzer şekilde yapılabilir sed -zE 's/\n([a-z])/ \1/g'(girdinin boş karakterleri olmadığı varsayılarak)
Sundeep

3
@Sundeep, ya da perl -Mopen=locale -0777 -pe 's/\n(?=[[:lower:]])/ /g'ASCII harfleriyle sınırlı kalmaması için.
Stéphane Chazelas

4

İle sedbir kullanabiliriz N;P;Ddöngüsü (bu nedenle her zaman için desen uzayda iki satır var ve yeni satır sonra ilk karakteri küçük harfli ise o zaman bir boşluk yeni satır değiştirin) ve test - Her sonra bu şekilde ssize döngüyü yeniden ubstitution:

sed -e :t -e '$!N;/\n[[:lower:]]/s/\n/ /;tt' -e 'P;D' infile

1
Sanırım burada neler olduğunu görüyorum, ancak genişletilmiş bir cevap sed döngülerini ve desen alanlarını çok sık kullanmayanlarımıza yardımcı olacaktır.
Joe

@Joe - "desen alanını çok sık kullanmamak" ile ne demek istiyorsun ? Neredeyse tüm işlemlerin gerçekleştiği yer - tutma alanı bir "depolama alanı" - oradayken verilerle hiçbir şey yapamazsınız. Her neyse, burada bir N;P;Ddöngünün nasıl çalıştığını ayrıntılı olarak açıkladım, bu yüzden tekrar üzerinden geçmeyeceğim. Buradaki fark, tbir şeyin değiştirilip değiştirilmediğini kontrol etmek için - test başarılı olursa, senaryonun üstüne dallıyoruz, aksi takdirde hiçbir şey değiştirilmedi ve P;Dyürütüldü. Hala belirsiz olup olmadığını bana bildirin.
don_crissti

3

Kullanılması sedve fmt:

$ sed -e '1n; s/^[[:upper:]]/\n&/' input.txt | fmt
This is one sentence that is broken.

However this is a good one.

And this one is somehow, broken into many.

Sed komut dosyası, büyük harfle başlayan her satırdan önce yeni bir satır ekler (ilk girdi satırı hariç). seddaha sonra çıktısıfmt elde edilen paragrafları yeniden biçimlendirmek için .

Alternatif olarak par, yüklediyseniz kullanın. Başka bir paragraf yeniden biçimlendirici, ancakfmt birçok özellik ve seçenekle birlikte, .

Her paragraf arasında boş bir satır olacağını unutmayın. Paragraflar gereken en az bir boş satır ile birbirinden ayrılabilir. Boş satırlar olmadan, tüm giriş örneğiniz tek bir çoklu cümle paragrafı olarak yeniden biçimlendirilir, örn:

$ fmt input.txt
This is one sentence that is broken.  However this is a good one.
And this one is somehow, broken into many.

Yeniden biçimlendirdikten sonra boş satırları kaldırmanız gerekiyorsa, yalnızca sedtekrar borulayın - ancak bu, orijinal girişte olabilecekler de dahil olmak üzere TÜM boş satırları kaldıracaktır. Örneğin

$ sed -e '1n; s/^[[:upper:]]/\n&/' input.txt | fmt | sed -e '/^$/d'
This is one sentence that is broken.
However this is a good one.
And this one is somehow, broken into many.

3

Bunu yapmanın başka bir yolu:

perl -lpe '$\ = /\.$/ ? $/ : $"' data

burada: $\=> ORS, $/=> IRS= \n, $"=space

perl -pe '$_ .= <>, eof or redo if s/[^.]\K\n/ /' data

sed -e '
   :a
      /\.$/!N
      s/\n/ /
   ta
' data

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.