我有一个包含许多条目的文件,其中包含一个关键字,后跟几行数字。我想过滤掉一类条目,因此如果条目 derp 后面跟着三行,我想要grep -v -A3 derp filename
获取文件名中不是 derp 类型的每个条目。问题是-v
并且-A
似乎是不兼容的。当使用两个标志时,-v
将被忽略。我还能怎样做呢?该文件如下所示:
SOURCE: pI < min 45 16 0 7.4871483836177132E-004 5.1628324610858206E-004 -1.826383220714803 -9.4293105782888549E-004 -6.8875048798939895E-002 -0.2196057448134437 -6.6270591049115615E-003 SOURCE: pI < min 45 17 0 7.1266687952112871E-004 5.1628324610858206E-004 -2.169039713847648 -1.1198388644036935E-003 -8.2240618017566103E-002 -9.0412967200093102E-005 -7.5453919169102962E-003 SOURCE: pI < min 45 18 0 7.0936181176839061E-004 5.1628324610858206E-004 -2.589392543137075 -1.3368599876201657E-003 -9.8187643312659903E-002 -1.1762198384731523E-005 -9.4417591779528513E-003
这以类似的方式持续了数千行。偶尔会有一个条目以 以外的内容开头SOURCE: pI < min
。我想找到的正是这些条目。该文件约为 50Mb。
答案1
我发现了一些有用的东西:
grep -A3 derp filename | diff - filename
答案2
从不同的方向做这件事怎么样?
sed '/pattern/,+3d' input_file
或者,如果您没有gnu sed
:
sed '/pattern/ {N;N;N;d;} input_file
将显示所有文本,减去包含该模式的任何行以及该行后面的 3 行。
或者如果您想就地编辑文件:
sed -i '/pattern/,+3d' input_file
如果-i
您的不支持sed
:
sed '/pattern/ {N;N;N;d;} inputfile > output_file
mv output_file input_file
这些基本上应该做你想要的......即包含一个文件
cat
dog
dog
dog
horse
如果这是我的模式,我只会得到horse
一个结果。cat
答案3
假设不需要的其他条目都是非数字的,您可以使用 构建它们的列表grep -v '^([0-9-]+|SOURCE:)' filename
。这会输出整个匹配行,因此需要进一步处理。
如果它们都遵循单词后跟冒号的模式,您可以使用awk -F: '!/^([0-9]+|SOURCE:)/ { print $1}'
.
获得列表后,您可以使用它来构建与所有这些列表匹配的正则表达式,然后在sed
每次找到其中一个匹配项时使用它来删除 4 行。
例如:
LIST=$(awk -F: '!/^([0-9-]+|SOURCE:)/ { print $1}' filename | sort -u)
RE=$(echo $LIST | sed -e 's/ /|/g')
sed -r -e "s/^($RE):/,4 d" filename
如果您需要在构建正则表达式之前对列表进行进一步处理,例如删除一些条目,您可以这样做:
RE=$(echo "$LIST" | egrep -v '^(FOO|BAR)$' | xargs echo | sed -e 's/ /|/g')
请注意这次 "$LIST" 周围的双引号 - 这会保留 egrep 使用的换行符(这就是为什么我们必须xargs echo
稍后通过管道来获取 一行中的所有列表条目sed
)。