Delete specific lines in a text file

Hi, experts,

I would like to create a function that can calculate the total number of lines in a saved text file and delete specific lines in that particular file (I only want the last few lines). Hav anybody have the experience and giv me a hand in this?

Do you want it the C way or the shell script way ?

Shell script way is quite easy as compared to the C way

Vino

maybe you are looking for this:
display the last 50 lines of something.txt

tail -n50 something.txt

there is also 'head' which displays the first few lines.

Hi,

I actually wanted to do it the C way. Yeah, it would be a lot easier using shell :slight_smile: My attempt is to keep only the final 100 lines in a text file, and throw the rest of the content, not meant for display only. I've searched through some books and website and found nothing so far.

Err well, typically you would identify a line by the presence of the '\n' character.

So, open the file. Go the end of the file. Work backwards towards the start of the file, counting the number of '\n'. When you have reached the required number of '\n' characters, store the position in the file.

Read from the stored position of the file to the end of file into memory buffer. Dump buffer contents into file.

Or something like that ...

Some useful functions are fopen, fclose, fread and fwrite.

Hope this helps.

MBB

This is a start

/* last100 */
/* usage - last100 <filename> lines_to_keep */
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

typedef int fildes;
/* read a buffer */
ssize_t readall(fildes fd, void *buf, size_t nbyte){
     ssize_t nread = 0;
     ssize_t n=0;

     do {
         if ((n = read(fd, &((char *)buf)[nread], nbyte - nread)) == -1) {
             if (errno == EINTR)
                 continue;
             else
                 return (-1);
         }
         if (n == 0)
             return nread;
         nread += n;
     } while (nread < nbyte);
     return nread;
}

char  *process_file(fildes in, char *buf, size_t *len)
{
	struct stat st;
    if (fstat(in,&st)==(-1) )          /* get file size in bytes */
    {
        perror("Cannot stat file");    /* error */
        exit(EXIT_FAILURE);
    }
    *len=(size_t)st.st_size+1;
    buf=malloc((size_t)st.st_size+1);          /* allocate memory for whole file */
    if(buf==NULL)
    {
        perror("Memory allocation failure");	/* mem error */
        exit(EXIT_FAILURE);
    }
    memset(buf,0x0,(size_t)st.st_size+1);
    if(readall(in,buf,(size_t) st.st_size)==(-1)) /* read in whole file */
    {
        perror("Error on file read");   /* error */
        exit(EXIT_FAILURE);	
    }
	return buf;
}

char *position_ptr(char *p,size_t *len, long linecount)
{
    size_t pos=*len;	
    while (pos && linecount>(-1))
    {
    	if( *(p+pos--)=='\n') linecount--;    	
    }
    p+=pos;
    p++; /* skip first newline */
    *len-=pos;
    return p;
}

int main(int argc, char *argv[])
{
    
    size_t len=0;
    char *buf=NULL;
    char *p=NULL;
    fildes in=open(argv[1],O_RDONLY);  /* low-level file open */
    
    if(in==(-1))                      /* error check */
    {
        perror("Error opening input file");
        exit(EXIT_FAILURE);
    }
    buf=process_file(in,buf,&len);
    p=position_ptr(buf,&len,atol(argv[2]));
    fprintf(stdout,"%s",p);
    free(buf);                        /* clean up and exit */    
    if(close(in))
    {
         perror("File close error");
         exit(EXIT_FAILURE);	
    }    
    return 0;
}

Hi, Jim,

I've tried out the code but it seems the libraries are not compatible to my unix system. It kept errored out with the "Function prototypes are an ANSI feature" and "Incompatible types in cast: Must cast from scalar to scalar or to void type". I am just at the beginner level, perhaps, you can give me a guide of what is it all about? :confused:

can you post the compiler output?

Oops... I played around with the code to make it work but failed to do so. I changed the type defined. Now, I am not able to duplicate the error now cos it does not look like the original file at all :stuck_out_tongue: i just wonder, izzit a library compatibality problem that makes me unable to compile the code?

jim mcnamara
very beautiful code ,thank you !!
I am a newbie.