使用 awk 删除没有后续内容行的 header 行

deleting header lines with no following content lines using awk

我想我已经做过几次了,但今天早上我做不到。 例如,我有一个这样的文件。 (这是使用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,一样)。我用 ### 'header' 行调用该行。逻辑是:我打印所有 non-header 行,但如果前一行是 header,则打印前一行。为此,我在 'kept' 变量中保留了任何 header 行。

<< file tt.awk >>

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

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

当我运行awk -f tt.awk gg时,我得到了这个结果。 'kept' 不是来自上一行而是来自当前行。 awk代码有什么问题? long-time awk 用户,我可能遗漏了一些重要的东西。

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

你想要的更简单:

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

要使现有代码正常工作,请替换:

    if (flag == 1) {print $kept; print [=10=];}

与:

    if (flag == 1) {print kept; print [=11=];}

其他方法

$ awk '/^###/{kept=[=12=];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=[=13=];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

使用 sed 方法

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

找到所有有模式的行并删除 或

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

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