一直在努力尝试,但仍然无法找到任何更明智的方法......
示例:
### this is the whole block structure ###
text_text_text
text_text_text
text_text_text
apple
### another block ###
text_text_text
text_text_text
text_text_text
orange
执行less <file_name> | grep -B3 "apple" | less
将返回:
text_text_text
text_text_text
text_text_text
apple
但现在我的要求是我不想要这个块(用苹果)。我确定我不想要什么,但不确定我想要什么。所以我不能这样做
less <file_name> | grep -B3 "orange" |less
如果我要:
less <file_name> | grep -v "apple" | less
然后只删除与苹果相关的单行,与苹果相关的块将保留在那里。
我试过
less <file_name> | grep -v -B3 "apple" | less
但这似乎不起作用。
那么有什么方法可以帮助我删除与苹果相关的块?
答案 0 :(得分:2)
删除不需要的块的一种方法是使用tac
和sed
。话说:
tac <filename> | sed '/apple/,+3d' | tac
将返回:
### this is the whole block structure ###
### another block ###
text_text_text
text_text_text
text_text_text
orange
获取样本数据。
说明:tac
反转文件中的行。 /apple/,+3
将匹配apple
和接下来的3行。 d
是delete
命令。
因为您需要删除模式apple
和之前的3行;我们反转文件中的行,找到apple
,删除它和接下来的3行,然后再次反转这些行以获得所需的结果。
您可能还想引用sed manual
。
答案 1 :(得分:0)
使用awk
并假设每个块长5个记录。
cat file
### anoter block ###
text_text_text
text_text_text
text_text_text
banan
### this is the whole block structure ###
text_text_text
text_text_text
text_text_text
apple
### another block ###
text_text_text
text_text_text
text_text_text
orange
awk '{a[NR]=$0} /apple/ {f=NR} END {for (i=1;i<=NR;i++) if (i<f-4 || i>f) print a[i]}'
### anoter block ###
text_text_text
text_text_text
text_text_text
banan
### another block ###
text_text_text
text_text_text
text_text_text
orange
答案 2 :(得分:0)
使用awk:
awk '/^apple$/{cs=0;next}
{ c[cs++]=$0 }
cs > 3 {
print c[0];
for (i=0;i<3;i++){c[i]=c[i+1]}; cs--;
}
END { for (i=0;i<cs;i++){print c[i]} }' input