linux下的文本文件处理

1.本文针对的文本文件格式类型是形如 linux系统标准服务配置文件的文本格式。比如dhcpd.conf中的

# option definitions common to all supported networks...
option      domain-name           "example.org";
option domain-name-servers    ns1.example.org, ns2.example.org;

对于形如windows标准配置文件格式的文件,比如

[optionName]

option1=item1;

option2=item2;

不做考虑。


2. linux文件操作的常规方法:

a。c语言解析。逐行获取逐行分析,开发效率比较低。

b。c语言+脚本语言。脚本语言包括lua,perl,shell,Ruby等。

经过比较,推荐shell或者lua。因为都是c语言开发的脚本语言,与c语言的结合相对比较好。

shell是unix posix的一部分,出现的时间早,因此资源相对丰富。可读性可维护性比shell差。

lua 可读性比shell好很多。不过考虑到资源丰富的问题,选择了shell。


3 shell + c 读取配置文件信息。

shell的基本教材推荐 http://see.xidian.edu.cn/cpp/view/6994.html。

放个例子上来,读取dhcpd.conf中的一个字段数据。

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>


static int my_system(const char* pCmd, char* pResult, int size,int* pOutLen);
int main(void)
{
    char result[1025];
    int iOutLen = 0;
    my_system("cat dhcpd.conf | awk '/^option[[:blank:]]+/ {print $3}'", result, 1025,&iOutLen);
 


   if (strlen(result) == iOutLen)
     printf("the result is: %s \r\n", result);
   else
   {
     int iTemp = 0;
     


     while(iOutLen)
     {
        iTemp += strlen(result+iTemp);
        
        printf("the result is :%s \r\n",result);
        iOutLen = iOutLen - iTemp;
        
     }
   }


    iOutLen = 0;
    my_system("sed -n '/^option/p' dhcpd.conf",result,1025,&iOutLen);

  
   if (strlen(result) == iOutLen)
     printf("the result is: %s \r\n", result);
   else
   {
     int iTemp = 0;
     


     while(iOutLen)
     {
        iTemp += strlen(result+iTemp);
        
        printf("the result is :%s \r\n",result);
        iOutLen = iOutLen - iTemp;
        
     }
   }

    return 0;



static int my_system(const char* pCmd, char* pResult, int size,int* pOutLen)
{
    int fd[2];
    int pid;
    int count;
    int left;
    char* p = 0;
    int maxlen = size-1;
    memset(pResult, 0, size);
    if(pipe(fd)) //创建管道
    {
        return -1;
    }
    if((pid = fork()) == 0) //创建子进程
    {// chile process
        int fd2[2];
        if(pipe(fd2))  //创建管道2
        {
            return -1;
        }
        close(1); //关闭系统标准输出1,即屏幕输出
        dup2(fd2[1],1); //将系统标准输出1重定向到文件描述fd2[1]中,fd2[1]是管道fd2的写入端。
        close(fd[0]);//关闭管道1的读入端
        close(fd2[1]);//关闭管道2的写入端
        system(pCmd);//执行命令
        read(fd2[0], pResult, maxlen); //从管道2中读取执行结果
        pResult[strlen(pResult)-1] = 0;
        write(fd[1], pResult, strlen(pResult)); //将执行结果pResult写入管道fd
        close(fd2[0]);//关闭管道fd2的读入端;
        exit(0);//子进程退出
    }
    // parent process
    close(fd[1]);
    p = pResult;
    left = maxlen;
    while((count = read(fd[0], p, left))) {
        p += count;
        left -= count;
        (*pOutLen) += count;//add by wangxya
        if(left == 0)
        break;
    }
    close(fd[0]);
    return 0;
}

执行结果为:

the result is: "example.org";
ns1.example.org, 
the result is: option      domain-name "example.org";
option domain-name-servers ns1.example.org, ns2.example.org; 


可以看到,awk擅长处理列数据;sed擅长处理行数据。

4.直接读取配置文件全部内容,且去掉注释行的方法:

my_system("sed '/^ *#/d' dhcpd.conf",result,1025,&iOutLen);

执行结果

the result is: 
ddns-update-style none;


option      domain-name "example.org";
option domain-name-servers ns1.example.org, ns2.example.org;


default-lease-time 600;
max-lease-time 7200;


log-facility local7;

5.直接读取配置文件全部内容,并去掉注释和空白行的方法

 my_system("sed  -n '/^\s*[^# \t].*$/p' dhcpd.conf",result,1025,&iOutLen);

执行结果为

the result is: ddns-update-style none;
option      domain-name "example.org";
option domain-name-servers ns1.example.org, ns2.example.org;
default-lease-time 600;
max-lease-time 7200;
log-facility local7; 


6.获取指定配置文件中第一行的第三列的且为option+空格开头的参数

my_system("sed  -n '/^\s*[^# \t].*$/p' dhcpd.conf | awk '/^option[[:blank:]]+/ {print $3}'| sed -n  '1p'",result,1025,&iOutLen);

执行结果

the result is: option param 3 itemp 1 is "example.org"; 


7.修改配置文件中的内容

命令行结果

 sed -i '/option/{/domain-name-servers/s/ns2.example.org/iwn.com.org/g}' dhcpd.conf

将记录

option domain-name-servers ns1.example.org, ns2.example.org;

修改为

option domain-name-servers ns1.example.org, iwn.com.org;


8.比较文件差异,并获取差异部分的命令:

原文连接:http://blog.xuyuan.me/2011/03/17/unix_diff.html

命令: diff temp1.txt temp2.txt | grep ">" | sed 's/> //g'

                  comm -13 temp1.txt temp2.txt

comm命令用来比较两个文件,具体用法:

comm [-123] file1 file2
-1 过滤file1独有的内容
-2 过滤file2独有的内容
-3 过滤file1和file2重复的内容


9.获取dhcpd.conf文件除掉注释和空白行以外的行数:

sed -n '/^\\s*[^#].*$/p' dhcpd.conf | sed '/^[[:space:]][[:space:]]*$/d' | sed -n '$='

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值