我在之前的答案中找到了以下 awk 脚本,用于根据模式将大文件拆分为较小的部分(用不同的模式替换“标题行”)。然而,我需要更进一步,因为可能会创建数百万个零件,但如果我可以再次过滤每个零件,它将得到我需要的东西。
awk '
/header-line/ {++part}
{print >sprintf("part-%03d.txt", part)}
'
是否可以在写入每个“部分”之前或之后询问该部分,以检查该部分中是否存在某种模式,并且仅在与附加模式匹配时将该部分写出。
例如,初始条件为“ID:”(上面的标题行)。然后我想搜索为特定方法名称创建的每个“部分”;将其称为“searchForThisMethod”作为要搜索的字符串,该字符串可能位于零件中的各个位置。
输入示例:
ID: 1
bb
bb
bb
bb
secondaryCheck
ID: 2
b
b
b
b
b
b
b
b
ID: 3
h
h
h
h
h
secondaryCheck
g
g
g
g
答案1
您可以拆分文件,然后grep -q some_method
在每个部分上运行并删除它,如果错误的例如
for file in part-*.txt; do
grep -q some_method "$file"
if [ $? -ne 0 ]
then
rm "$file"
fi
done
或
使用两遍 - 从输入中删除包含的“部分”,some_method
然后分割结果,例如用于sed
第一遍和awk
第二遍的代码:
sed -e '1{h;d;}' -e '/ID/!{H;$!d;}' -e 'x;/some_method/!d' infile | \
awk '/ID/{++part}{print > sprintf("part-%03d.txt", part)}'
sed
将第一行复制到h
旧缓冲区上并删除它,然后附加与旧缓冲区d
不匹配的每一行,如果不是最后一行则将其删除,并且 e更改匹配的行上的缓冲区,如果不包含则删除模式空间。然后结果通过管道传输到.如果出现错误,则必须使用以下文件:ID
H
x
ID
some_method
awk
too many open files
close()
sed -e '1{h;d;}' -e '/ID/!{H;$!d;}' -e 'x;/some_method/!d' infile | \
awk '/ID/{++part}{close(fn);fn=sprintf("part-%03d.txt", part);print >> fn}'
或者,如果你在gnu
/anything 上,你可以使用csplit
而不是awk
:
sed '1{h;d};/ID/!{H;$!d};x;/some_method/!d' infile | \
csplit -f 'part-' -b '%03d.txt' -sz - /ID/ '{*}'