我正在努力全神贯注于这项任务。我想从以下输出中排除所有包含的行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 .