Newsgroup: it.comp.lang.c
Titolo: grep????

come faccio ad eseguire grep da dentro un programma?
sto cercando disperatamente della documentazione 
in rete ma non ne ho ancora trovato...
grazie a chi rispondera'...

Su quale piattaforma lavori?
mi hanno dato un compilatore (turbo c) per dos
e per ora sto lavorando su quello
vorrei poi convertire il tutto su linux!!(quando ne so
qualcosina in +)

 in rete ma non ne ho ancora trovato...
Su quale piattaforma lavori?
-- 
     (ZZZ)       Filippo Salotti, Bagni di Lucca, Lucca, Italy.
    //   \\  _                 E-mail : 
fil...@humnet.unipi.it
   /Y\    ZD<_o===============================================o
 .oZZZZZo.     | Studente Ingegneria Informatica Automatica  |
<OXXXXXXXO>    | Dip. Sistemi Elettrici Universita' di Pisa. |

 qualcosina in +)
La soluzione e' fortemente dipendente dalla piattaforma su cui lavori,
quello che va per linux quasi sicuramente non e' funzionante in dos.
In linux per lanciare un programma esiste la famiglia primitive exec
(execl, execvp...) che permettono di specificare il nome del programma i
parametri sulla riga di comando e un eventuale ambiente.
Con il comando 'man exec' troverai tutta la documentazione dettagliata.
Anche in dos esisteva qualcosa di simile (anche qui exec credo).
Ciao.


come faccio ad eseguire grep da dentro un programma?
Se hai un eseguibile chiamato grep, sul "percorso di ricerca"
usato per gli eseguibili, allora, su qualsiasi macchina,
    system("grep");
lo _deve_ mandare in esecuzione, a standard C ISO.
Se devi passargli anche degli argomenti, anch'essi
dovranno allora far parte della stringa passata a system
(il separatore fra argomenti non e` standardizzato, ma
in pratica uno spazio funzona su tutti i sistemi che
conosco):
    system("grep pippo pluto.txt");
Alex


wrote:

questo funziona, pero' dovrei fare una cosa del genere:
da scanf ho un input da tastiera, col grep dovrei 
cercare in un insieme di file, se esiste quella stringa
quindi se il risultato di grep e' zero (non la trovo)
scrivo la stringa sul mio file....
grazie ancora

scrivo la stringa sul mio file....
A rigor di standard, system(), invocata con un argomento
non nullo, dovrebbe tornare:
    0    se e solo se la shell (o altro meccanismo equivalente
          comunque usato per eseguire il comando) torna 0
    -1   in caso di errore (con errno settato di conseguenza)
altro   quello che ha tornato la shell in risposta alla richiesta
Bisogna vedere se le librerie standard del tuo compilatore,
e la shell che esse usano, collaborano correttamente da
questo punto di vista.  Se si`, allora l'approccio sarebbe
qualcosa del tipo:
void writeIfFound(const char* targetString, FILE* outfile)
{
    int rc;
    char *buffer = malloc(strlen("grep ") +
        strlen(targetString) + stren(" *.txt"));
    if(!buffer) /* segnala errore di mancanza di memoria
        poi longjmp oppure */ return;
    strcpy(buffer, "grep ");
    strcat(buffer, targetString);
    strcat(buffer, " *.txt");
    rc = system(buffer);
    free(buffer);
    if(rc == -1) /* segnala errore ecc ecc */ 
        return;
    if(rc == 0) 
        fputs(targetString, outfile);
}
Purtroppo questo approccio e` "fragile", a seconda del
contenuto di targetString.  Ad esempio, se targetString
contiene spazi, la shell (che system implicitamente usa)
riterra` che il primo di questi spazi termini la stringa da
cercare, e quanto segue siano nomi di file su cui cercare;
se contiene una barra verticale, cerchera` di eseguire un
"pipe" da grep (su standard input) verso altri comandi; e
via pazziando.
Le soluzioni possono essere:
-- preprocessare targetString, sottoponendo a "quoting"
    o "escaping" tutti gli eventuali caratteri speciali che essa
    contiene, a seconda delle regole della shell usata (non
    tutte le shell usano, ahime`, regole identiche) -- usare
    la versione cosi` preprocessata per comporre il comando
    di grep, quella originale per scrivere su file (se del caso);
-- rinunciare alla portabilita` e ricorrere invece a soluzioni
   non portabili, dipendenti dal sistema, come fork ed exec,
   oppure spawn, eccetera, che possono essere + robuste;
-- rinunciare ad usare grep ed effettuare invece la ricerca
   da dentro il programma stesso (usando una libreria di
   gestione delle regular-expression, e la rete ne abbonda,
   non e` per nulla difficile)
Sono tutte soluzioni ragionevoli in diversi contesti (ad esempio,
visto che raramente i comandi stessi che si eseguono possono
essere molto portabili, la "portabilita`" garantita dalla system e`
abbastanza relativa -- benche` certo superiore a fork+exec,
che fuori da Unix/Linux non funziona, mentre di grep.exe per
vari altri ambienti se ne trovano facilmente).  Per questo specifico
problema suggerirei la terza alternativa, ma, in altri casi di
"comandi esterni" di funzionalita` non cosi` facilmente duplicabile,
la seconda puo` essere preferibile.
Alex

...
:     [snip]
: >da scanf ho un input da tastiera, col grep dovrei 
: >cercare in un insieme di file, se esiste quella stringa
: >quindi se il risultato di grep e' zero (non la trovo)
: >scrivo la stringa sul mio file....
[ snip ]
: Purtroppo questo approccio e` "fragile", a seconda del
: contenuto di targetString.  Ad esempio, se targetString
: contiene spazi, la shell (che system implicitamente usa)
: riterra` che il primo di questi spazi termini la stringa da
: cercare, e quanto segue siano nomi di file su cui cercare;
: se contiene una barra verticale, cerchera` di eseguire un
: "pipe" da grep (su standard input) verso altri comandi; e
: via pazziando.
Da come Orsetto descrive il problema, una possibile soluzione 
potrebbe essere quella di quotare targetString con gli apici 
semplici (').
Riprendendo il tuo codice:
void writeIfFound(const char* targetString, FILE* outfile)
{
    int rc;
    char *buffer = malloc(strlen("grep ") +
        strlen(targetString) + 2 + strlen(" *.txt"));
    if(!buffer) /* segnala errore di mancanza di memoria
        poi longjmp oppure */ return;
    sprintf(buffer, "%s'%s'%s", "grep ", targetString, " *.txt");
    ...ecc.
}
In tal modo la shell non tentera' di interpretare targetString
(perlomeno sotto UNIX/Linux).
Pero' non so se questo approccio possa funzionare sotto DOS...
Ciao ciao,
Andrea
-- 
"...Unix, MS-DOS, and Windows NT (also known as the Good, the Bad, and 
 the Ugly)."
(by Matt Welsh)

        fputs(targetString, outfile);
si ma con system () il sistema mi da sempre 0
e con execv () sempre -1!!!!
uso winDoZe 98 con il compilatore Turbo C 
della Borland 
grazie ancora

Andrea Foco (
big...@fokhouse.flashnet.it
) wrote:
[ snip ]
: void writeIfFound(const char* targetString, FILE* outfile)
: {
:     int rc;
:     char *buffer = malloc(strlen("grep ") +
:         strlen(targetString) + 2 + strlen(" *.txt"));
ERRATA CORRIGE ;)
Ovviamente, per tener conto dello '\0' finale, buffer va 
dimensionato come:
      char *buffer = malloc(strlen("grep ") + strlen(targetString)
			    + 2 + strlen(" *.txt") + 1);


e con execv () sempre -1!!!!
con sprintf invece sempre -21!!!!


uso winDoZe 98 con il compilatore Turbo C 
Mi pare che Turbo C fosse un compilatore per DOS, giusto?
Puo` darsi che non supporti bene l'ambiente Win32.
Prova a scaricare un compilatore gratuito e aggiornato,
come egcs 1.1.1 o lcc per Win32, e vedi se vanno meglio.
Alex


wrote:

quale va meglio ???
i'm confused....
thanks

i'm confused....
lcc e` molto piu` piccolo, e quindi facile da scaricare; egcs
e` molto piu` grosso e ricco, con qualche vantaggio in
termini di ottimizzazioni (e supporto per altri linguaggi,
come C++, Fortran, ecc, che non e` detto ti interessino).
lcc comprende un ambientino di sviluppo (mi pare), egcs
di per se` e` solo un compilatore+strumenti, senza IDE.
Insomma, vanno bene tutti e due, e sono entrambi gratis;
l'uno, o l'altro, dovrebbero comunque andarti meglio di
un antico compilatore per DOS.
Alex

semplici (').
Mi pare che questo darebbe un problema se targetString
contenesse gia` un apice-semplice.  Il quoting per i vari
shell (di Unix, simil-Unix, e non-Unix), soffre spesso di
qualche irregolarita`.
Alex

come egcs 1.1.1 o lcc per Win32, e vedi se vanno meglio.
allora ho scaricato lcc e mi da lo stesso errore di turbo c
o meglio devo aver combinato qualche casino io....
questo e' il mio listato:
#include <stdio.h>
#include <alloc.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <dos.h>
char *strupr (char *str);
char gianni [8];
char prova [8];
int i;
int rc;
int k;
int selezione (void);
int inserimento (void);
FILE *scrivoinput;
FILE *scrivioutput;
void cerca (const char* gianni,FILE* scrivioutput)
{
	int rc;
	char *buffer=malloc(strlen("grep ")+strlen(gianni)+strlen("
gianni.txt"));
	if (!buffer) return;
	strcpy (buffer, "grep ");
	strcat (buffer,gianni);
	strcat (buffer," *.txt");
	rc = system (buffer);
	free (buffer);
	if (rc == -1) return;
	if (rc == 0)
	   scrivioutput = fopen ("gianni.txt","a+");
	   fputs (gianni, scrivioutput),
	   fputs ("\n",scrivioutput);
	   fclose (scrivioutput);
}
main ()
{
	inserimento ();
	return 0;
}
inserimento ()
{
	printf ("\nINSERIRE BARCODE\n");
	gets (gianni);
	strupr (gianni);
	if (strlen (gianni) < 8)
		printf ("il barcode inserito non e' esatto"),
		gets ("\n");
	/*controlla che se la stringa Š superiore a otto caratteri*/
	else if (strlen (gianni) >8)
		printf ("ATTENZIONE! REINSERISCI IL BARCODE!\n"),
		printf ("PREMI INVIO !!!"),
		gets ("\n");
	/*scansione  per controllo errori.....*/
	else if (gianni[0]!='X')
		printf ("il barcode inserito non e' esatto"),
		gets ("\n");
	else if (gianni[1] !='C')
		printf ("il barcode inserito non e' esatto"),
		gets ("\n");
	/*verifico che la stringa (dopo il prefisso) sia un numero*/
	else if (gianni[2]<'0'|gianni[2]>'9')
		printf ("il barcode inserito non e' esatto"),
		gets ("\n");
	/*verifico che la stringa (dopo il prefisso) sia un numero*/
	else if (gianni[3]<'0'|gianni[3]>'9')
		printf ("il barcode inserito non e' esatto"),
		gets ("\n");
	else if (gianni[4]<'0'|gianni[4]>'9')
		printf ("il barcode inserito non e' esatto"),
		gets ("\n");
	else if (gianni[5]<'0'|gianni[5]>'9')
		printf ("il barcode inserito non e' esatto"),
		gets ("\n");
	else if (gianni[6]<'0'|gianni[6]>'9')
		printf ("il barcode inserito non e' esatto"),
		gets ("\n");
	else if (gianni[7]<'0'|gianni[7]>'9')
		printf ("il barcode inserito non e' esatto"),
		gets ("\n");
	cerca (gianni,"gianni.txt");
	return 0;
}
secondo me sbaglio quando vado a chiamare la funzione cerca
gli argomenti si passano cosi'?
(non e' da molto che  uso il c.....)
grazie ancora!!!

gli argomenti si passano cosi'?
Ci sono una marea di problemi. Uno di questi, in effetti,
e` che hai dichiarato che la cerca prende come 2o
argomento un FILE*, e invece gli passi un char*.  Un
altro, gravissimo, e` che dichiari un array di 8 char
dove (cosi` suggerisce il test con strlen) ti aspetti
di leggere almeno 8 caratteri, piu` naturalmente lo
0 di terminazione, quindi, almeno 9 (sara` dunque
meglio che lo dimensioni ad ALMENO 9, no?).  E` poi
sempre fonte di confusione dare gli stessi nomi a
variabili globali e argomenti formali di una funzione.
Alex

variabili globali e argomenti formali di una funzione.
adesso dovrei averli cambiati 
ma non funziona ancora....
il bello e che a video la stringa me la fa vedere....
pero' 
rc = system (buffer);
mi restituisce sempre 0
che altro ho combinato????

...
:     [snip]
: >Da come Orsetto descrive il problema, una possibile soluzione
: >potrebbe essere quella di quotare targetString con gli apici
: >semplici (').
: Mi pare che questo darebbe un problema se targetString
: contenesse gia` un apice-semplice.
Vero. Ma si tratterebbe di considerare a parte unicamente
questo caso (facendo una ricerca in targetString per il
carattere ').
: Il quoting per i vari shell (di Unix, simil-Unix, e non-Unix),
: soffre spesso di qualche irregolarita`.
Infatti, e questo e' probabilmente il problema piu' grosso.


 carattere ').
Non so se è applicabile a questo caso ma in Visual Basic si usa spesso
delimitare con due doppi apici che sono molto più difficili da trovare
all'interno di una stringa.
EMG

 void cerca (const char* gianni,FILE* scrivioutput)
Forse volevi scrivere
void cerca (const char* gianni,const char* filename)
e poi
scrivioutput = fopen (filename,"a+");
EMG


ok dopo tutto questo 
nel debug a video vedo grep che
mi spara le stringhe nello schermo corrette
ma la variabiel rc e' sempre a zero!!!!
secondo me il problema e' un'altro ....
sta diventando un incubo .....