关于linux文本的处理,包括数据报表或LOG等文本处理的问题

中山野鬼 发布于 2012/04/07 15:58
阅读 630
收藏 1

咨询大家,现在都用什么方案?

这两天写MAKEFILE实例,遇到个脚本设计,把A文件整体插入到B文件的某个指定匹配行的前面。

目前我用的方案只能是,对A文件一行行的读,然后插入到B文件。

这等于B文件有N次扫描,N等于A的文件行数。

我用的是bash脚本下,使用sed,但没用sed脚本。

大家有否更好的方式,给点意见。

一直不太喜欢用脚本方式处理文本。有这个功夫我用C都写完动态的了。但现在为了发帖子,还得折腾脚本,当然BASH下的脚本我确实不是很熟练。望高手给予点心得分享。

加载中
0
红薯
红薯
脚本不在行啊,遇到这种问题为了节省时间,俺都直接写一小程序搞定。
0
皮总
皮总

sed -i '/^1/ r a.txt' b.txt

将 a.txt 的内容插入 b.txt 中以1开头的行后面

皮总
皮总
@红薯 : 薯总,前面没仔细看题目,如何在前面插入另外一个文件的内容我也不会~
红薯
红薯
我怎么还不会 sed 呢,真自卑:(
0
中山野鬼
中山野鬼
我在考虑是否针对文本的绝大多数通用性的操作,实现个文本快速编辑的程序。老外的sed ,awk,tr真TMD不是人用的。逻辑稍微有点复杂就大爷大了。
0
中山野鬼
中山野鬼

引用来自“皮总”的答案

sed -i '/^1/ r a.txt' b.txt

将 a.txt 的内容插入 b.txt 中以1开头的行后面

目前还没有办法在当前行之前插入行。是否有什么好方案?

也即如果我查找到字符串 ABCD,我希望是从另一个文件读取的文本,插入在ABCD行前面。这个我一直没有关注。r 的命令我当初简单试过。也因为一时找不到好方法,能插入式读取所以没用。

0
中山野鬼
中山野鬼

引用来自“皮总”的答案

sed -i '/^1/ r a.txt' b.txt

将 a.txt 的内容插入 b.txt 中以1开头的行后面

目前我能试成功的做法,只能先找到对应行,然后前插一个特殊的字符串,然后再根据这个字符串进行文本加入,最后再删除掉这个特殊字符串所在的行。不知到是否还有更简介的方案。
0
vzex
vzex
###以下代码保存为insert.awk
BEGIN {
        bFind=0;
}
{
        if ( bFind==0 && $0 ~ /match_reg/)
        {
                while((getline l<f)>0)
                {
                        print l;
                }
                close f;
                bFind=1;
        }
        print;
}
####

调用:
1 上面的match_reg替换成你要的正则表达式
2 假设:文件f2插到f1里面,调用 awk -v "f=f2" -f insert.awk f1

0
中山野鬼
中山野鬼

引用来自“vzex”的答案

###以下代码保存为insert.awk
BEGIN {
        bFind=0;
}
{
        if ( bFind==0 && $0 ~ /match_reg/)
        {
                while((getline l<f)>0)
                {
                        print l;
                }
                close f;
                bFind=1;
        }
        print;
}
####

调用:
1 上面的match_reg替换成你要的正则表达式
2 假设:文件f2插到f1里面,调用 awk -v "f=f2" -f insert.awk f1

多谢。但是这样做实际上还是双扫描。一个是扫描定位到需要处理的文本的所有符合条件的行,另一次是将插入的文本按照行依次插入,就是你的while循环。这样仍然没有效率。虽然整体文本的读取,sed r的方式,确实可以直接读取一次上来,但是我目前智能又多上替换行重新定位的方式,获取当前判断条件的前一行。
0
vzex
vzex
没有理解你说的双扫描是啥意思,awk 中以{}包含的代码段是在处理文件的每一行的时候调用的。当开关关闭时,去查找匹配行,匹配不到就直接print当前行内容,匹配到了的话就先print另外的文件的所有内容,然后再print当前行内容,之后开关关闭,剩余行就不会再做匹配了,直接print(不知道是不是你说的那个扫描的意思)。
0
vzex
vzex

那段awk代码其实近似于c++的这段伪代码

bool bFind=false;

xxx=fopen(A)

while(line=fgets(xxx))

{

    if(!bFind&&strstr(line,xx))

    {

        //readfile B and print

        bFind=true;

    }

    printf(line);

}

我猜lz可能误解了吧,不过这个合并结果还要先写到临时文件,再mv回A。linux下mv就是改个节点名,所以说还是很快的

0
中山野鬼
中山野鬼

引用来自“vzex”的答案

没有理解你说的双扫描是啥意思,awk 中以{}包含的代码段是在处理文件的每一行的时候调用的。当开关关闭时,去查找匹配行,匹配不到就直接print当前行内容,匹配到了的话就先print另外的文件的所有内容,然后再print当前行内容,之后开关关闭,剩余行就不会再做匹配了,直接print(不知道是不是你说的那个扫描的意思)。

双扫描可以这样理解。假设A文件放到B文件里某个匹配成立处。A文件有100行,B文件有1000行。

假设B文件中可匹配处未知。则应该对B进行1000行的分析并查找。这个是没有错的。但对于每次匹配成功,则根据上面的while则是读取了100次每次100行,进行插入。这和上面用 r方式的朋友,属于一次读取A文件,还是有些差异的。

极端的说假设在每行都插入,那么r的方式是1000次。每次一个整体问题。上述做法是1000次插入动作中,存在100次读取。

返回顶部
顶部