Eliminare le righe vuota da file di testo

Postate qui per tutte le discussioni legate a Linux in generale.

Moderatore: Staff

Regole del forum
1) Citare sempre la versione di Slackware usata, la versione del Kernel e magari anche la versione della libreria coinvolta. Questi dati aiutano le persone che possono rispondere.
2) Per evitare confusione prego inserire in questo forum solo topic che riguardano appunto Gnu/Linux in genere, se l'argomento è specifico alla Slackware usate uno dei forum Slackware o Slackware64.
3) Leggere attentamente le risposte ricevute
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Rispondi
Avatar utente
venerdi_12
Packager
Packager
Messaggi: 258
Iscritto il: sab 9 lug 2005, 0:00
Nome Cognome: Luciano Fattore
Kernel: 3.0
Desktop: kde-4.7.0
Distribuzione: archlinux
Località: Lusciano (Ce)

Eliminare le righe vuota da file di testo

Messaggio da venerdi_12 »

Quasi mi vergogno :oops:
Come faccio ad eliminare una riga vuota (l'ultima, nello specifico) da un file di testo?
Ho molti file .ram da convertire in mp3 ma ognuno ha alla fine una riga vuota che mplayer non digerisce.
Pensavo a sed, ma quale espressione regolare devo usare?
grazie

albatrosla
Packager
Packager
Messaggi: 1339
Iscritto il: sab 27 mar 2004, 0:00
Slackware: current
Desktop: fluxbox.git
Località: Collegno, but made in Friûl
Contatta:

Messaggio da albatrosla »

http://www.student.northpark.edu/pement ... d1line.txt
Questa è la migliore guida online che ho trovato... Se non trovi nulla di "decente", si può fare con uno script che ho pensato ora e scritto di pugno (gli amanti della programmazione magari inorridiranno!):

Codice: Seleziona tutto

#!/bin/bash
n=`cat -n lucy.txt | tail -n1| cut -f1`                                         
n=`expr $n - 1`                                                                 
head -n$n $1 > $1_cut 
Ciò che ti dà in output è un file pari all'originale ma privo dell'ultima riga, nominato come nome_file_originale_cut. La sintassi è: script.sh nome_file_originale.
E' pure semplice fare in modo che ti dia la possibilità di specificare il nome del file di output da linea di comando...

Avatar utente
venerdi_12
Packager
Packager
Messaggi: 258
Iscritto il: sab 9 lug 2005, 0:00
Nome Cognome: Luciano Fattore
Kernel: 3.0
Desktop: kde-4.7.0
Distribuzione: archlinux
Località: Lusciano (Ce)

Messaggio da venerdi_12 »

Albatros_la ha scritto:

Codice: Seleziona tutto

#!/bin/bash
n=`cat -n lucy.txt | tail -n1| cut -f1`                                         
n=`expr $n - 1`                                                                 
head -n$n $1 > $1_cut 
Purtroppo non funge... La prima cosa che avevo pensato era head.
Se puoi prova con questo ram:
http://www.radio.rai.it/radio2/alleotto ... _12_27.ram

grazie

Avatar utente
masalapianta
Iper Master
Iper Master
Messaggi: 2775
Iscritto il: lun 25 lug 2005, 0:00
Nome Cognome: famoso porco
Kernel: uname -r
Desktop: awesome
Distribuzione: Debian
Località: Roma
Contatta:

Messaggio da masalapianta »

sed '/^$/d' file > file_senza_righe_vuote

Avatar utente
venerdi_12
Packager
Packager
Messaggi: 258
Iscritto il: sab 9 lug 2005, 0:00
Nome Cognome: Luciano Fattore
Kernel: 3.0
Desktop: kde-4.7.0
Distribuzione: archlinux
Località: Lusciano (Ce)

Messaggio da venerdi_12 »

masalapianta ha scritto:sed '/^$/d' file > file_senza_righe_vuote
Non vorrei insistere, ma non funziona. Queste soluzioni le avevo trovato googlando prima di chiedere qui.
Se potete provate con il link più sopra. :(

Avatar utente
balzarini
Linux 0.x
Linux 0.x
Messaggi: 39
Iscritto il: gio 23 mar 2006, 16:40
Località: Varese

Messaggio da balzarini »

Se con riga vuota intendi dover togliere solo gli ultimi caratteri di newline e/o linefeed,
allora prova a salvare questo in un file.c:

Codice: Seleziona tutto

#include<stdio.h>

int  main( int argc, char **argv)
{   int     index;
    FILE    *fp;
    long    lengthToSave;
    long    lengthToDelete;
    char    lastTestedChar;
    char    *commandString;
    for( index=1; index<argc; index++)
    {
        //    examine the file to get the number of bytes to keep from it
        fp = fopen( argv[ index], "r");
        if( fp == NULL )
        {
            //    ignore wrong file names
            continue;
        }

        //printf( "opened %s\n", argv[ index]);
        for( lengthToDelete=-1L;; lengthToDelete--)
        {
            if( fseek( fp, lengthToDelete, SEEK_END) )
            {    //    ignore empty files
                //printf( "err1\n");
                lengthToSave = 0L;
                break;
            }

            if( fread( &lastTestedChar, 1, 1, fp) == 0)
            {    //    ignore empty files
                //printf( "err2\n");
                lengthToSave = 0L;
                break;
            }

            if( (lastTestedChar == '\n') || (lastTestedChar == '\r') )
            {    //    memorize useful number of bytes
                lengthToSave = ftell( fp);
                //printf( "good test (%c) implies lengthToSave == %lu\n", lastTestedChar, lengthToSave);
            }
            else
            {    //    no more chars will be ignored
                //printf( "final test (%c) implies lengthToSave == %lu and exit\n", lastTestedChar, lengthToSave);
                break;
            }
        }

        fclose( fp);

        if( lengthToSave > 1L )
        {
            lengthToSave--;
            commandString = (char *) malloc( strlen( argv[ index]) * 2 + 128);
            sprintf( commandString, "head --bytes=%lu %s > dele.teme ; mv dele.teme %s\n", lengthToSave, argv[ index], argv[ index]);
            //printf( "%s", commandString);
            system( commandString);
            free( commandString);
        }
    }
    return 0;
}
poi fai:
gcc file.c -o pulisci

poi fai:

pulisci *.ram

se devi ripulire la coda di tutti i file .ram di una directory...oggi c'ho proprio un :- da fare al lavoro!

Avatar utente
balzarini
Linux 0.x
Linux 0.x
Messaggi: 39
Iscritto il: gio 23 mar 2006, 16:40
Località: Varese

Messaggio da balzarini »

ah ecco, non avevo visto che il "file.ram" in realta` e` un file di testo!
Allora bastava usare gli script gia` postati eliminando due caratteri, non uno...
comunque il mio programmino dovrebbe essere utile lo stesso.

Altrimenti nella bash scrivi:
for F in `ls *.ram`
do
head -c -2 $F > dele.teme ; mv dele.teme $F
done

ATTENTO a non farlo due volte sugli stessi file!!!

Avatar utente
masalapianta
Iper Master
Iper Master
Messaggi: 2775
Iscritto il: lun 25 lug 2005, 0:00
Nome Cognome: famoso porco
Kernel: uname -r
Desktop: awesome
Distribuzione: Debian
Località: Roma
Contatta:

Messaggio da masalapianta »

venerdi_12 ha scritto:
masalapianta ha scritto:sed '/^$/d' file > file_senza_righe_vuote
Non vorrei insistere, ma non funziona. Queste soluzioni le avevo trovato googlando prima di chiedere qui.
Se potete provate con il link più sopra. :(
invece funziona, quel comando elimina tutte le righe vuote da un file di testo, che e' quello che avevi chiesto, se invece volevi fare altro spiegati meglio

Avatar utente
balzarini
Linux 0.x
Linux 0.x
Messaggi: 39
Iscritto il: gio 23 mar 2006, 16:40
Località: Varese

Messaggio da balzarini »

Probabilmente ti dice che "non funziona" perche` i file .ram che deve filtrare hanno dentro
i caratteri 10 e 13 per fare il ritorno a capo (perche` magari arrivano da window), mentre i
vostri script mi sembra rimuovano solo il 10!

Il programma in c che ho postato funziona sicuramente, anche lo script funziona, ma non
controlla se gli ultimi caratteri sono proprio da eliminare o no.

albatrosla
Packager
Packager
Messaggi: 1339
Iscritto il: sab 27 mar 2004, 0:00
Slackware: current
Desktop: fluxbox.git
Località: Collegno, but made in Friûl
Contatta:

Messaggio da albatrosla »

Chiedo scusa: ho fatto un errore banale nel codice che avevo postato! Era rimasto specializzato rispetto al nome del file di test che avevo usato!
Questo è il codice corretto:

Codice: Seleziona tutto

#!/bin/bash
n=`cat -n $1 | tail -n1| cut -f1`                                         
n=`expr $n - 1`                                                                 
head -n$n $1 > $1_cut

Avatar utente
venerdi_12
Packager
Packager
Messaggi: 258
Iscritto il: sab 9 lug 2005, 0:00
Nome Cognome: Luciano Fattore
Kernel: 3.0
Desktop: kde-4.7.0
Distribuzione: archlinux
Località: Lusciano (Ce)

Messaggio da venerdi_12 »

balzarini ha scritto:Probabilmente ti dice che "non funziona" perche` i file .ram che deve filtrare hanno dentro
i caratteri 10 e 13 per fare il ritorno a capo (perche` magari arrivano da window), mentre i
vostri script mi sembra rimuovano solo il 10!

Il programma in c che ho postato funziona sicuramente, anche lo script funziona, ma non
controlla se gli ultimi caratteri sono proprio da eliminare o no.
Infatti è così. Grazie per le dritte :)

Avatar utente
venerdi_12
Packager
Packager
Messaggi: 258
Iscritto il: sab 9 lug 2005, 0:00
Nome Cognome: Luciano Fattore
Kernel: 3.0
Desktop: kde-4.7.0
Distribuzione: archlinux
Località: Lusciano (Ce)

Messaggio da venerdi_12 »

masalapianta ha scritto: invece funziona, quel comando elimina tutte le righe vuote da un file di testo, che e' quello che avevi chiesto, se invece volevi fare altro spiegati meglio
Come hai potuto vedere non poteva funzionare, anche perché io avevo chiesto:
Come faccio ad eliminare una riga vuota (l'ultima, nello specifico) da un file di testo?
Ho molti file .ram da convertire in mp3 ma ognuno ha alla fine una riga vuota che mplayer non digerisce.
E avevo anche detto:
Spero di essermi spiegato, adesso :wink:
Grazie a tutti.

P.S.
Invito i maghi della shell a dare un'occhiata allo script incluso nel thread:
script per creare un "mirror" locale di un reposit
http://www.slacky.it/forum/viewtopic.ph ... highlight=
Avrebbe bisogno di un po' di miglioramenti e consigli.
Se ne esce qualcosa di buono potremmo metterlo nella sezione script di Slacky...

Avatar utente
Paoletta
Staff
Staff
Messaggi: 3975
Iscritto il: lun 25 apr 2005, 0:00
Slackware: 14.2 - 64 bit
Desktop: fluxbox
Località: Varese

Messaggio da Paoletta »

Codice: Seleziona tutto

if( lengthToSave > 1L )
        {
            lengthToSave--;
            commandString = (char *) malloc( strlen( argv[ index]) * 2 + 128);
            sprintf( commandString, "head --bytes=%lu %s > dele.teme ; mv dele.teme %s\n", lengthToSave, argv[ index], argv[ index]);
            //printf( "%s", commandString);
            system( commandString);
            free( commandString);
        }
    } 
balzarini perché usi la shell? é piú pulito cosí:

Codice: Seleziona tutto

if( lengthToSave > 1L )
        {
	             lengthToSave--;
	             fseek( fp, 0, SEEK_SET);
	             fout = fopen(argv[ index], "w");
	             char mybuf[lengthToSave];
	             fread(mybuf,1,lengthToSave,fp);
	             fwrite(mybuf,1,lengthToSave,fout);
	             fclose(fp);
	             fclose(fout);
	      
        }
usando un'altra modalitá di fopen penso che si possa aprire uno stream solo per il tutto...

Avatar utente
balzarini
Linux 0.x
Linux 0.x
Messaggi: 39
Iscritto il: gio 23 mar 2006, 16:40
Località: Varese

Messaggio da balzarini »

balzarini perché usi la shell? é piú pulito cosí:

Codice: Seleziona tutto

if( lengthToSave > 1L )
        {
                lengthToSave--;
                fseek( fp, 0, SEEK_SET);
                fout = fopen(argv[ index], "w");
                char mybuf[lengthToSave];
                fread(mybuf,1,lengthToSave,fp);
                fwrite(mybuf,1,lengthToSave,fout);
                fclose(fp);
                fclose(fout);
        
        } 
bhe, ho usato la shell per gioco visto che non avevo un caspio da fare al lavoro...poi, se
proprio si vuole farlo tutto in c, allora non puoi aprire in modalita` "w" il file e leggerlo perche`
se usi "w" te lo cancella...andava letto tutto alla prima apertura usando "rw" (che spreco di
memoria...) e scritto colla fwrite che dici tu...e poi e` c non c++ e non potresti mettere il
"char mybuf[lengthToSave]" li` perche` le dichiarazioni vanno all'inizio delle funzioni
e non puoi nemmeno fare array con dimensione variabile ... poi devo solo stare zitto perche`
ho messo i comenti col // che non sono standard nemmeno loro :oops:
Saro` mica andato OT?
Non stimolatemi troppo sul c che poi divento pallosamente prolisso e cicerone...anzi lo sono
gia` diventato :)

Avatar utente
Paoletta
Staff
Staff
Messaggi: 3975
Iscritto il: lun 25 apr 2005, 0:00
Slackware: 14.2 - 64 bit
Desktop: fluxbox
Località: Varese

Messaggio da Paoletta »

balzarini ha scritto:
se proprio si vuole farlo tutto in c, allora non puoi aprire in modalita` "w" il file e leggerlo perche`
se usi "w" te lo cancella...andava letto tutto alla prima apertura usando "rw" (che spreco di
memoria...) e scritto colla fwrite che dici tu...e poi e` c non c++ e non potresti mettere il
"char mybuf[lengthToSave]" li` perche` le dichiarazioni vanno all'inizio delle funzioni
e non puoi nemmeno fare array con dimensione variabile ...
che dire, la mia variante non é ansi ma funziona (come la tua del resto); :wink: mi sembrava stravagante usare la shell per qualcosa che si puó fare senza troppa fatica pure in c :wink: ;inoltre il buffer non é una array con dimensione variabile, é semplicmente una variabile semidinamica, che viene referenziata indirettamente in compilazione e durante l'esecuzione viene allocata in cima al record di attivazione della funzione

EDIT: nel caso servisse a qualcuno anche solo per curiositá ecco la versione del programmino che compila con

Codice: Seleziona tutto

gcc -ansi -Wall -o pulisci pulisci.c

Codice: Seleziona tutto

#include<stdio.h>

int  main( int argc, char **argv)
{   int     index;
 FILE    *fp,*fout;
 long    lengthToSave=0;
 long    lengthToDelete;
 char    lastTestedChar;
 for( index=1; index<argc; index++)
   {
     fp = fopen( argv[ index], "r");
     if( fp == NULL )
       continue;
     for( lengthToDelete=-1L;; lengthToDelete--)
       {
	 if( fseek( fp, lengthToDelete, SEEK_END) )
	   {
	     lengthToSave = 0L;
	     break;
	   }

	 if( fread( &lastTestedChar, 1, 1, fp) == 0)
	   {
	     lengthToSave = 0L;
	     break;
	   }
	 
	 if( (lastTestedChar == '\n') || (lastTestedChar == '\r') ){
	   lengthToSave = ftell( fp);
	 }
	 else
	   break;
       }
     if( lengthToSave > 1L )
       {
	 lengthToSave--;
	 fseek( fp, 0, SEEK_SET);
	 fout = fopen(argv[ index], "w");
	 char mybuf[lengthToSave];
	 fread(mybuf,1,lengthToSave,fp);
	 fwrite(mybuf,1,lengthToSave,fout);
	 fclose(fp);
	 fclose(fout);
        
       } 
   }
 return 0;
} 

Rispondi