我想知道是否可以删除除最后一个之外的所选图案的所有行。解释起来并不容易,所以我会举一个例子。
我有一个内容与此类似的文本文件:
A sent (1)
A received (1)
B sent (1)
B sent (2)
B sent (3)
B received (1)
我希望在“已发送”和“已接收”消息之间进行更改,其中“已发送”消息是具有相同字母的已发送消息之间的最后一个消息。所以我需要一个输出:
A sent (1)
A received (1)
B sent (3)
B received (1)
是否有某些程序可以做类似的事情?我可以使用Ubuntu或Windows,或者在必要时构建一个简单的C / C ++应用程序。
答案 0 :(得分:2)
这是一个简单的方法:
tac FILE | uniq -w 6 | tac
我们:
tac
反向打印文件(uniq
必须在此处工作)。tac
。答案 1 :(得分:1)
在linux下,这可以是单行,例如awk
:
awk '$1 $2 != prev {if (buf) print buf} {prev = $1 $2; buf = $0} END {print buf}' mylog.txt
确切的语法取决于您的模式。在这里,我只使用该行的前两个单词($1 $2
)来确定是否应该跳过一行。跳过的行($0
)存储在临时中,当模式不同或END
时打印。
如果可以打印类似块的第一行而不是最后一行,则脚本将缩减为:
awk '$1 $2 != prev; {prev = $1 $2}' mylog.txt
或者您可以使用更简洁的替代方案:
uniq -w 6
排序唯一的行,但只考虑前6个字符。
答案 2 :(得分:0)
在C中,这样的事情会发生:
bool isFirstSent = false;
bool isSecondSent = false;
char *firstLine = getLine(file); // getline returns a char array
// if a line exists and NULL otherwise
if (strstr(firstLine, "sent"))
isFirstSent = true;
char *secondLine = getLine(file);
while (secondLine)
{
if (strstr(secondLine, "sent"))
isSecondSent = true;
else
isSecondSent = false;
if (isFirstSent != isSecondSent)
printf("%s", firstLine);
free(firstLine);
isFirstSent = isSecondSent;
firstLine = secondLine;
secondLine = getLine(file);
}
free(firstLine);