【问题标题】:deleting header lines with no following content lines using awk使用 awk 删除没有以下内容行的标题行
【发布时间】:2015-02-12 02:12:10
【问题描述】:

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

<< 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 时,我得到了这个结果。 “保留”不是来自上一行,而是来自当前行。 awk 代码有什么问题? awk 的老用户,我可能错过了一些重要的东西。

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

【问题讨论】:

  • 问题是$kept。您不要在普通的 awk 变量上使用 $$1 等是实际名称。所以你想要print kept。话虽如此,John1024 答案的其他变化也很好。使用内置的模式匹配动作而不是if等。

标签: awk sed gawk


【解决方案1】:

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

    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

【讨论】:

  • 我明白了。你的建议看起来更好。谢谢!
【解决方案2】:

你想要的更简单:

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

【讨论】:

    【解决方案3】:

    使用 sed 方法

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

    找到所有带有patter的行并删除 或

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-14
      • 1970-01-01
      • 2016-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-08
      相关资源
      最近更新 更多