日期:2014-05-16  浏览次数:20616 次

linux文件内容拷贝的问题
请问:
在linux中,需要把文件出现abcd字符之前的部分拷贝到一个文件中,abcd及之后的内容拷贝到另外一个文件中,请问怎么用linux shell脚本或者linux C编程实现?

先谢谢啦~

------解决方案--------------------
c 程序的话,可以把整个文件的内容都读入一个字符串,然后查找abcd,再分头写入两个文件就行了
------解决方案--------------------
shell 基本上都是处理文本行的
------解决方案--------------------
sed awk
试试
------解决方案--------------------
新手写了一个,如有不对,请见谅并指教。
C/C++ code

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>

int main(void)
{
    char str[50]="";
    printf("please input the separative string, ex. \"abcd\"\n");
    scanf("%s",str);
    int fd1=open("file.txt",O_RDONLY);
    if(fd1==-1) perror("open file.txt failed"),exit(-1);
    int fd2=open("befor.txt",O_RDWR|O_CREAT|O_TRUNC,0666);
    if(fd2==-1) perror("create befor.txt failed"),exit(-1);
    int fd3=open("after.txt",O_RDWR|O_CREAT|O_TRUNC,0666);
    if(fd3==-1) perror("create after.txt failed"),exit(-1);
    char first=' ';
    int len=strlen(str);
    char buff[len];
    buff[len-1]='\0';
    int readCount;
    while((readCount=read(fd1,&first,1))!=0)
    {
        
        if(readCount==-1) printf("error\n"),exit(-2);
        if(first==str[0]) {//先比较第一个字符是不是'a';            
            read(fd1,buff,len-1);
            if(strcmp(buff,str+1)==0) {//如果第一个字符是'a',就接着比较'a'后面的字符串
                off_t afterBeg=lseek(fd1,0,SEEK_CUR);//后半段的开始位置
                off_t beforEnd=lseek(fd1,-len,SEEK_CUR);//前半段的结束位置
                off_t beforBeg=lseek(fd1,0,SEEK_SET);
                long beforSize=beforEnd-beforBeg;
                int count=0;
                int lastRead=beforSize%256;//每次读256个字节,最后一次读的大小 
                while(count<beforSize-lastRead) {
                    char fileBuff[256]="";
                    int readSize=read(fd1,fileBuff,sizeof(fileBuff));
                    if(readSize==-1) perror("read failed"),exit(-3);
                    count+=readSize;    
                    write(fd2,fileBuff,readSize);
                }
                char fileBuff[256]="";
                int readSize=read(fd1,fileBuff,lastRead);
                write(fd2,fileBuff,lastRead);
                close(fd2);
                lseek(fd1,afterBeg,SEEK_SET);//将后半段写到after.txt
                while(readSize=read(fd1,fileBuff,sizeof(fileBuff))) {        
                    if(readSize==-1) perror("read failed"),exit(-3);    
                    write(fd3,fileBuff,readSize);
                }
                close(fd1);
                close(fd3);
                return 0;
                
            }else {
                lseek(fd1,-(len-1),SEEK_CUR);//第一个字符是'a',但是后面不匹配,就要回退len-1字节
                continue;
            }
            
        }
    }
    printf("string:%s not found in file\n",str);
    return 1;
}

------解决方案--------------------
找abcd是有编程技巧的,因为可能abcd被两次读入, 所以每一次读入前应该将前一次读入的末尾3个字符留在缓冲区内, 再次读的数据追加到缓冲区, 在里面找abcd, 祝你能理解这个的重要性。
------解决方案--------------------
C/C++ code


/*****
请问:
在linux中,需要把文件出现abcd字符之前的部分拷贝到一个文件中,abcd及之后的内容拷贝到另外一个文件中,
请问怎么用linux shell脚本或者linux C编程实现?
*****/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    FILE *fp;
    FILE *before;
    FILE *after;
    char *p = NULL;
    int ch;
    char *separate_str = "abcd";
    int SIZE = strlen(separate_str);
    
    char queue_str[SIZE+1];//用数组作为队列,用来缓存从文件中读出的字符
    if ((fp = fopen("file.txt", "r")) == NULL)
    {
        printf("open file.txt error !");
        exit(1);
    }
    
    if ((before = fopen("