Pagina 1 di 1
Eliminare le righe vuota da file di testo
Inviato: gio 11 mag 2006, 22:22
da venerdi_12
Quasi mi vergogno
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
Inviato: gio 11 mag 2006, 22:36
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...
Inviato: gio 11 mag 2006, 23:10
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
Inviato: gio 11 mag 2006, 23:57
da masalapianta
sed '/^$/d' file > file_senza_righe_vuote
Inviato: ven 12 mag 2006, 8:03
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.

Inviato: ven 12 mag 2006, 10:22
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!
Inviato: ven 12 mag 2006, 10:53
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!!!
Inviato: ven 12 mag 2006, 13:00
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
Inviato: ven 12 mag 2006, 13:53
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.
Inviato: ven 12 mag 2006, 14:28
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
Inviato: ven 12 mag 2006, 18:09
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

Inviato: ven 12 mag 2006, 19:12
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

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...
Inviato: sab 13 mag 2006, 10:36
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...
Inviato: mer 17 mag 2006, 17:39
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

Saro` mica andato OT?
Non stimolatemi troppo sul c che poi divento pallosamente prolisso e cicerone...anzi lo sono
gia` diventato

Inviato: mer 17 mag 2006, 17:52
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);

mi sembrava stravagante usare la shell per qualcosa che si puó fare senza troppa fatica pure in c

;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
#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;
}