使用awk删除没有以下内容行的标题行

时间:2015-02-12 02:12:11

标签: awk sed gawk

我想我已经做了几次,但今天早上我不能这样做。 我有一个像这样的文件。 (这是使用foreach和diff比较许多文件的结果,文件名用###模式括起来)

<< file gg >>

### ./translations/qt_fr.ts ###
### ./translations/qt_es.ts ###
### ./translations/qt_help_hu.ts ###
### ./transla file 1 _help_hu.ts ###
< alala0
------
> blabla0
### ./translations/qt_help_hu.ts ###
### ./translations/qt_help_hu.ts ###
### ./translations/qt_help_hu.ts ###
### ./translations/qt_help_hu.ts ###
### ./translations/qt_help_hu.ts ###
### ./transl file 2 t_help_hu.ts ###
< alala0
< alala1
--------
> blabla0
> blabla1
### ./translations/qt_help_hu.ts ###
### ./translations/qt_help_hu.ts ###
### ./translations/qt_help_hu.ts ###
### ./translations/qt_help_hu.ts ###
### ./translations/qt_help_hu.ts ###

我想要做的是删除那些只有文件名的行,以产生如下所示的输出。

(expected output)

### ./transla file 1 _help_hu.ts ###
< alala0
------
> blabla0
### ./transl file 2 t_help_hu.ts ###
< alala0
< alala1
--------
> blabla0
> blabla1

我怎么能用awk做这个?我试过这个(我试着让它看起来像C,同样)。我用###&#39;标题&#39;线。逻辑是:我打印所有非标题行,但如果前一行是标题,则打印上一行。为此,我将所有标题行保留在&#39;保持&#39;变量。

<< file tt.awk >>

{if ($0 !~ /^###/)
        if (flag == 1) {print $kept; print $0;}
        else {print $0}
}

{if  ($0 ~ /^###/)
        flag = 1;
else
        flag = 0;
kept = $0;
}

当我运行awk -f tt.awk gg时,我得到了这个结果。 &#39;保持&#39;不是前一行而是当前行。 awk代码有什么问题?一个长期的awk用户,我可能会遗漏一些重要的东西。

< alala0
< alala0
------
> blabla0
< alala0
< alala0
< alala1
--------
> blabla0
> blabla1

3 个答案:

答案 0 :(得分:2)

要使现有代码有效,请替换:

    if (flag == 1) {print $kept; print $0;}

使用:

    if (flag == 1) {print kept; print $0;}

其他方法

$ awk '/^###/{kept=$0;f=1;next} f {print kept} {f=0;print}' gg
### ./transla file 1 _help_hu.ts ###
< alala0
------
> blabla0
### ./transl file 2 t_help_hu.ts ###
< alala0
< alala1
--------
> blabla0
> blabla1

为简单起见,可以删除标记f

$ awk '/^###/{kept=$0;next} kept {print kept} {kept="";print}' gg
### ./transla file 1 _help_hu.ts ###
< alala0
------
> blabla0
### ./transl file 2 t_help_hu.ts ###
< alala0
< alala1
--------
> blabla0
> blabla1

答案 1 :(得分:1)

你想要的更简单:

{
    if ($0 ~ /^###/)
    { kept = $0; flag=1; }
    else if (flag == 1) {print kept; print $0; flag=0}
    else {print $0}
}

答案 2 :(得分:0)

使用sed方法

sed '/^###.*###/d' file

查找带有pattern和delete的所有行 或

sed -n '/^###.*###/!p' file

查找所有没有模式的行###并打印