如何打印所有不包含字符串的行以及相邻行?

如何打印所有不包含字符串的行以及相邻行?

我正在努力全神贯注于这项任务。我想从以下输出中排除所有包含的行Auto-installed: 1和之前的两行。我天真地认为这grep -v -B2 string会解决问题......不用说,只会让情况变得更糟。

这是内容:

Package: libopencore-amrwb0
Architecture: amd64
Auto-Installed: 1

Package: transfig
Architecture: amd64
Auto-Installed: 0

Package: xfig-libs
Architecture: amd64
Auto-Installed: 1

Package: xaw3dg
Architecture: amd64
Auto-Installed: 0

结果如下:

Package: transfig
Architecture: amd64
Auto-Installed: 0

Package: xaw3dg
Architecture: amd64
Auto-Installed: 0

(注意,空行不显示,如果不显示空行是一个加号,但不是必需的,结果还应包括自动安装值为 0 的软件包)

我知道我可以匹配换行符但要么不打印任何内容,要么打印所有内容,但中间会出现换行。

任何解决方案都可以接受,不必是 grep (它甚至可以是 emacs)。

答案1

我不确定您的数据的结构如何,但如果正如您所显示的那样,那么以下内容如何:

grep -B2 'Auto-Installed: [^1]'

这假设每个节都包含一行Auto-Installed,这可能不正确。

这是一个 awk 程序,我认为它完全按照您的要求执行。

awk 'BEGIN{deleted=3}
     !deleted{printf "%s",l[NR%3]}
     deleted {--deleted}
     {l[NR%3]=/./?$0"\n":$0}
     /Auto-Installed: 1/{deleted=3}
     END{for(i=NR+deleted;i<NR+3;++i)printf "%s",l[i%3]}'

答案2

我想这会做你

sed ':a
     $!N                          # slurp
     /Auto-Installed: 1/s/.*//    # kill all buffered on match
     $!{/\n.*\n/{P;D}}            # P/D any third line, D cycles w/o read
     $!ba                         # if no P/D, cycle w/o read anyway
    '

答案3

与其尝试排除它们,为什么不直接选择相反的行,而这正是您想要的呢?

$ grep -B 2 "Auto-Installed: 0" data.txt 
Package: transfig
Architecture: amd64
Auto-Installed: 0

排除具有“自动安装:1”的部分

如果您想使用grep但使用您的逻辑来解决排除包含“自动安装:1”的部分的问题,我没有使用以下方法提出这种方法PCRE设施在 GNU grep 中。

$ grep -B2 -P 'Auto-Installed: (?!1)' data.txt 

例子

$ grep -B2 -P 'Auto-Installed: (?!1)' data.txt 
Package: transfig
Architecture: amd64
Auto-Installed: 0

上面利用了Perl 的前瞻功能, (?!..).这使我们能够在 后查找不包含值 1 的行进行匹配Auto-Installed:。然后我们告诉在“匹配”之前grep显示 2 行 ( )。-B2

答案4

这是强制性的 Perl 方式:

perl -000ne 'print unless /Auto-Installed: 1/' file

神奇的是-000,这打开了 Perl 的段落模式这使得它将文件分成段落。换句话说,记录由两个或多个连续\n字符分隔。

这还将打印条目之间的空行,为了摆脱它,你可以运行

perl -000ne 'print unless /Auto-Installed: 1/' file | grep .

相关内容