Newsgroup: it.comp.os.linux.iniziare
Titolo: Mettere periodi su una sola riga: regex sed vim etc

Ciao a tutti,
 
Mi stavo chiedendo come trasformare un file di testo semplice
costituito da righe generiche, alcune spezzate dove capita
(magari per rispettare una certa larghezza di colonna), mentre
altre sono la riga finale di un periodo e giustamente sono
"spezzate" dopo il punto.
 
Scusate in anticipo la simpatia del seguente esempio!!!  :(((
 
-----
Questo
è il
periodo
spezzatino.
Quest'altro
invece è
il periodo
fettine.
-----
 
Deve diventare
-----
Questo è il periodo spezzatino.
Quest'altro invece è il periodo fettine.
-----
 
In pratica voglio che il testo vada a capo solo dopo il punto.
Da quello che ho visto, realizzare questa operazione con sed
sembra piuttosto complicato... non credevo.
 
Siccome utilizzo vim, se avete qualche idea di come sia possibile
realizzarlo con quest'ultimo, magari in visual mode: del tipo che
seleziono il testo da trattare, applico il comando e ottengo la
modifica sopra esemplificata.
 
Anche altre soluzioni sono benaccette tipo awk, perl o quello
che vi viene in mente e vi sembra più adatto.
 
Grazie in anticipo!
Saluti  :)

 -----
 
Sta roba sembra funzionare:
 
sed ':a;N;$!ba;s/\([^\.]\)\n/\1 /g'
 
Non è bella a vedersi, però và...
 
Da come ho capito carica nel buffer di sed tutte le righe
altrimenti i newline sed non riesce ad intercettarli, come
se fossero "oltre" il fine riga.
Quindi la parte
 
:a;N;$!ba
 
serve proprio per questo: mette tutto il testo da trattare
in buffer.
Dopodichè applico la sostituzione dei newlines, tranne quelli
preceduti da un punto. Forse c'era un modo più elegante per
scriverlo, ma mi accontento.
 
Come dicevo sarei però interessato anche ad alternative
in particolare come realizzare quella trasformazione
da dentro vim in modo da farne uso più interattivo,
scegliendo attraverso la visual mode le parti di testo da
trattare.
 
Attendo fiducioso!  :)

 Ciao a tutti,
 
Ciao!

L'"a capo" sempre e solo dopo il punto lo fai al volo:
tr '\n' ' ' < file_origine | sed 's/\. /\.\n/g' > file_destinazione
(provalo che l'ho scritto direttamete qui senza testarlo)
 
Pero' il fatto e' che cosi' fai un pasticcio, perche' mischi i periodi
coi paragrafi.. voglio dire: il "Punto a capo lettera maiuscola", che
dettava la maestra, era un cambio di paragrafo, altrimenti non si va
a capo.
 
A macchina, o a stampa, i paragrafi vengono ancor piu' evidenziati da
altri due modi: rientro della prima riga o riga vuota.
 
Comunque ci sono programmi per farlo, io pero' non ne conosco; con
l'ottimo mcedit ad esempio basta dare alt-p e ti formatta il paragrafo,
portandosi col cursore al successivo se usi riga vuota, cosi' vai
velocissimo a formattare tutto perche' tieni premuto alt e batti p p
p p p.. -- ciao
 
Ps. Occhio pero' che il comando qui su ti cancella ogni riga vuota.
 
Ps2. Ma che differenza c'e' tra spezzatino e fettine? mica si capisce!
 
-- 
Yoda
 

 Ps2. Ma che differenza c'e' tra spezzatino e fettine? mica si capisce!
 
Sempre carne fatta a pezzi è.... Sarai mica vegano, venerabile amico?
:))

> Ps. Occhio pero' che il comando qui su ti cancella ogni riga vuota.
 
Vero.
Sono comunque riuscito a risolvere sia con sed che con vim, e con
una sola fava:
 
sed ':a;N;$!ba;s/\([^\. \t]\)\n/\1 /' raw.txt
 
Allora, il comando sopra come avevo già scritto in altro post
è complicato perchè sed deve prendere tutto il file in buffer
prima di riuscire a gestire ed intercettare i "newline", per
cui la prima parte del comando serve a quello:
 
:a;N$!ba;
 
Poi però il resto è abbastanza semplice:
all'ultimo carattere prima del newline più il newline finale,
si sostituisce l'ultimo carattere prima del newline più uno spazio
 
cioè a questo:
 
\(ultimocarattere\)\n
 
sostituisco questo (ho aggiunto le virgolette solo per far vedere
che c'è uno spazio dopo l'uno):
 
"\1 "
 
 
questo in ogni riga, tranne in quelle in cui il newline finale è
preceduto dal "punto", o dallo "spazio", o dalla "tabulatura".
 
Ed ecco allorra che al posto di "ultimocarattere" devo mettere una
regex che intercetta tutti i caratteri tranne quelli da escludere
cioè appunto il punto, lo spazio, la tab.
 
ultimocarattere = [^\. \t]
 
la tegolina iniziale dentro la parentesi quadra esclude i caratteri
che la seguono:
 
il punto che va "protetto" col backslash
 
"\."
 
lo spazio
 
" "
 
la tab che si richiama con
 
"\t"
 
-------------------------
 
Ok, perdonate la spiegazione... proprio da icol.iniziare!!!  :))
 
Veniamo all'utilizzo di sta roba con vim.
Si può fare!
Ed è più semplice, basta dire che il comando è lo stesso
identico appena visto tranne la parte relativa al buffer.
 
Quindi imamginimo di avere aperto con vim il nostro rax.txt.
 
- andiamo in visual mode con "V" o con "v"
- selezioniamo il testo da trattarre
- e digitiamo
 
:s/\([^\. \t]\)\n/\1 /
 
- diamo invio e fine del discorso...
 
Questo lascia le righe vuote, ed porta su un'unica riga tutti
i periodi spezzati appunto su più righe.
Ha l'inconveniente che se le righe terminano per spazio o per
tab, non vengono toccate... per cui dipende un po' dal testo
che dobbiamo trattare.
Per quello che serve a me sembra funzionare discretamente.
 
Aggiungo che per comodità conviene associarlo ad un tasto
speciale o ad una combinazione di tasti da impostare in vim,
in modo da:
- andare in visual con V
- selezionare il testo da trattare
- premere il tasto associato, o la combinazione associata
 
Per esempio io ho scelto il tasto <F2> e l'ho impostato
in modo che quando sono in visualmode applichi la sostituzione
descritta al testo selezionato. Ecco come appare l'impostazione
nelò file di configurazione di vim:
 
~/.vimrc
---------
vmap  <F2>          :s/\([^\.]\)\n/\1 / <CR>
-----
 
Per il momento a me basta questo.
Però se vi viene in mente qualche altra soluzione postate
pure.
 
A me per esempio viene in mente "par", il tool per formattare
i paragrafi, che si può richiamare anche da dentro vim...
Però anche lui le righe vuote le ignora e anche il punto
finale, ma probabilmente c'è il modo di dargli il comando
giusto per lo scopo:
http://www.nicemice.net/par/
 
 
Se ne sapete di più benvenga...
 
 
 
L'ho fatta lunga, spero che serva a qualcuno... sicuramente
a me quando mi sarò dimenticato di tutto questo e ne avrò
bisogno di di nuovo! :D
 
Buona giornata!  :)

 bisogno di di nuovo! :D
 
L'avevo gia' intravista ieri la prima parte della riga di comando di sed,
non canoscevo assolutamente tutta questa sintassi di sed, me la guardero'
completamente ma con calma, e' proprio molto interessante! Ciao
 
Ps. Per caso proprio ieri guardavo colorit, che chiama il preprocessore
m4. Be'.. se ci butti un occhio e' roba da fantascienza in confronto ai
nostri sed! e apropos: c'e' un suo script che si chiama wrap.m4.. !
 
-- 
bye, Yoda
 


È questo?
 
https://www.mankier.com/1/colorit
 
 
Sinceramente non lo conoscevo, ma non saprei bene da dove iniziare
per capire come funziona e per capire se possa tornare utile allo
scopo. Resta un oggetto misterioso per me...
Lo script wrap dovrebbe essere questo:
 
/usr/doc/m4-1.4.17/examples/wrap.m4
------------------------------------
divert(-1)
m4wrap(`Wrapper no. 1
')
 
m4wrap(`Wrapper no. 2
m4wrap(`Wrapper no. 3
m4wrap(`Wrapper no. 4
')')')
divert
No. 33: The End.
----------------
 
Ma, anche qui, non che ci abbia capito qualcosa...
 
Hai qualche link ad esempi di come sta roba viene usata in pratica?
O se lo conosci vorresti magari spiegare anche solo a grandi linee
in cosa consiste, come si usa e in quali casi può essere impiegato?
 
Grazie mille!
 

 in cosa consiste, come si usa e in quali casi può essere impiegato?
 
Dunque.
Colorit, e quindi m4, e' da pochissimo che l'ho scoperto.
Uso dict, con decine di dizionari, da riga di comando.
Il programma colorit e' nel pacchetto dict.
Colorit usa m4.
A m4 occorre dare in pasto uno script d'istruzioni, del quale il modello
per default che ha coloit equivale (grosso modo) a questo script per sed:
s/espressione_regolare/AmedesimaZ/g
s/espressione_regolare2/BmedesimaZ/g
...eccetera...
dove A,B.. sono le sequenze escape per fore e beckground dei colori e Z
e' quella per tornare al default della console (cioe' "\33[m").
 
Te l'avevo scritto perche' e' chiaro che m4 e' vastissimo e ha tutti
gli script gia' fatti, magari -avevo pensato- c'e' anche quello tuo.
Ciao e se ci sono novita' comcrete ci sentiamo!
 
Ps. La man di colorit dice che serve anche per diff, pero' diff ce l'ha
gia' interno suo ed e' splendido -- l'hai visto? Io lo uso con questo
script perche' odio gli indirizzi di riga che ci mette:
=-=-=-=-=-=-=-=-=-
#! /bin/bash
 
diff --color=always $1 $2 | sed 's/^ctrl-esc[36m.*/\n--------------->/'
=-=-=-=-=-=-=-=-=-=-=-
 
(ctrl-esc l'ho scritto qui se no slrn mi dice che e' vietato, ma e'
l'ottale 33 cioe' 0x1b, in console lo batti con: ctrl-v e poi esc)
 
 
-- 
bye, Yoda
 

 gia' interno suo ed e' splendido -- l'hai visto?
 
No, sinceramente non sono sceso così in profondità!  :D
Ma mi fido!!!  :)
 
Ti saluto

 il testo con gli a capo come nel pdf, cioè a casaccio.
 
Se e' dai pdf che viene il testo, allora dovresti/potresti avere anche
altri problemi, dipende dal tipo e versione del pdf. Se contiene foto
invece che testo bisogna vedere come lo rende l'ocr. A me ad esempio
molto spesso, con pdftotext, le accentate gravi mi venivano "a `" o
addirittura "a `\n" o "a \n`", cioe' col newline -- un disastro!
 
Ma io -- astutissimo ;^) -- avevo fatto come ora ti dico.
$: pdftohtml -s -i -noframes aaa.pdf aaa.html
$: html2text -utf8 aaa.html aaa
 
ora infatti e' l'ottimo html2text che te lo formatta. Prova!
 
Ad esempio Il pozzo e il pendolo, preso da liberliber, viene perfetto
(o quasi: mette il numero di pagina ma magari ti piace; talvolta restano
spazi multipli che pero' elimini al volo dopo con "tr -s ' '").
Comunque e' tutto a 72 caratteri/riga di default, che puoi cambiare.
 
Ciao e fammi sapere!
 
-- 
bye, Yoda
 

 ora infatti e' l'ottimo html2text che te lo formatta. Prova!
 
Premetto che nel mio caso il pdf di partenza contiene testo
già digitalizzato, quindi non immagini di scansioni.
 
Ho provato il tuo metodo, ma ottengo un testo meno facile
da rimaneggiare, con righe vuote qua e là, difficili da trattare
con una regex generica (non so se mi spiego...), cioè con
pdftotext le righe erano spezzate, ma tra di esse non c'erano
delle righe vuote, così la mia regex dei messaggi precedenti
funzionava in modo accettabile in combinata con la selezione
manuale del testo da trattare.
Con queste due passate pdf->html->txt oltre alle righe spezzate
ne ho anche molte più vuote e come osservavi anche tu appaiono
dei doppi spazi che poi devi trattare a parte..
In definitiva meglio restare su pdftotext, basandomi sulla prova
che ho fatto io, relativa al pdf che ho sottomano. Magari in
altri casi cambia.
 
 
 
Il tuo comando html2text però non mi torna, che tool hai usato
di preciso?
Io ho trovato questo... installato su slackware con un pacchetto
del repo SBo:
https://pypi.python.org/pypi/html2text
 
 
e usato così:
 
html2text aaa.html utf8 > aaa.txt
 
Poi ho provato così:
 
 
html2text -b0 aaa.html utf8 > aaa.txt
 
Cioè larghezza corpo del testo infinita...
Ma il problema resta, secondo me perchè le righe spezzate si creano
nel primo passaggio da pdf ad html con pdftohtml.
 
 
PS.
Apro un'altro topic per chiedere consigli su OCR da scansioni
o da pdf composti da immagini delle pagine scansionate.

>> 
========================================================================

 di preciso?
 
Il pacchetto html2text e' stato rimaneggiato dalla Debian, ha alcune
caratteristiche aggiunte, per questo da te andava male.
 
Comunque ci sono novita'. Smanettando con mcview che mi fa le tabelle
perfette e html3text invece le pasticcia, ho scoperto che mcview sai
cosa fa? semplicemente questo: "w3m -dump pippo.html".
Dunque ti consiglio:
1. passa ORIG.pdf a DEST.html con pdftohtml, che ti mantiene
l'allineamento e l'impaginazione.
 
2. e poi dai semplicemente:
$: w3m -dump DEST.html > finale_tuo
 
N.B. Bada di metterci l'estensione ".html" altrimenti w3m non capisce,
percio' non provare nemmeno a metterlo in pipe: deve leggere da file
su disco.
 
Ciao e fammi sapere!
 
Postilla. Tu forse hai lynx o links, invece mettiti w3m che e'
specializzato proprio per le tabelle e i frame e poi anche per
essere usato coi file per queste conversioni ariciao
 
-- 
Yoda
 

 essere usato coi file per queste conversioni ariciao
 
Ricorda sempre che tutta sta solfa la eseguo per lo scopo
finale:
 
scopo finale
PDF  --->  EPUB
---------------
PDF ---> TXT   ok
 
PDF ---> HTML  non buono
 
TXT ---> EPUB  vedi sopra la procedura semi-automatica che
               sto valutando.

                sto valutando.
 
Due cose al volo che non ho tempo:
 
1. guarda che c'e' un 3d qui su: "awk per stampare le 3 righe..." dove
dando il row.txt in pasto a awk ti fa al volo tutto il lavoraccio di vi.
 
2. Ma le hai guardate le utility-tool dei pacchetti epub? Ciao!
 
3 (mai 2 senza). Te lo sei installato w3m? perche' la velocissima Slack
usa lynx se non ha cambiato adesso; be', c'e' un abisso e mcview di
default li chiama tutti: lynx links w3m, quindi da te chiamerebbe lynx.
 
-- 
bye, Yoda
 

 default li chiama tutti: lynx links w3m, quindi da te chiamerebbe lynx.
 
Rileggi il mio precedente post quando puoi...
Il punto è: perchè devo passare da pdf ad html? Se dopo devo passare
da html a txt, quando posso subito passare da pdf direttamente a txt?
 
Con la mia procedura sopra l'html me lo ricostruisco io alla fine quando
ho un testo semplice in ordine, con gli a capo al posto giusto, le righe
vuote al posto giusto e le tabelle un minimo allineate.
 
Non mi serve passare da pdf a html per poi passare a txt e infine
costruire l'epub praticamente riaggiungendo vari tag html. Tanto vale
passare subito da pdf a txt e da lì ad epub/html. Non so se mi sono
spiegato...
 
mcview come ho scritto prima visualizza il pdf usando "pdftotext -layout",
non passa da html...