以下是否有更清洁的解决方案?
grep INFO messages | head -1
grep INFO messages | tail -1
INFO或消息的长度是随机的。
答案 0 :(得分:6)
尝试:
grep INFO messages | sed -n '1p;$p'
grep - 将从消息文件中搜索模式 sed -n' 1p; $ p' - 将打印第一(1p)和最后($ p)行
答案 1 :(得分:3)
您可以使用-m
来确定您想要的匹配数量:
第一个:
grep -m1 "INFO" messages
最后,让我们用tac
向后打印文件,然后使用相同的逻辑:
tac messages | grep -m1 "INFO"
这样,您可以避免处理整个文件两次:您只需处理它直到找到匹配项。
来自man grep
:
-m NUM, - max-count = NUM
NUM匹配行后停止读取文件。如果输入是 来自常规文件的标准输入和NUM匹配行 输出,grep确保标准输入定位到just 在退出之前的最后一个匹配行之后,无论如何 存在尾随上下文行。这使得调用进程成为可能 恢复搜索。当grep在NUM个匹配行后停止时,它 输出任何尾随上下文行。当-c或--count选项是 也使用,grep不输出大于NUM的计数。当-v 或 - 也使用--invert-match选项,输出后grep停止 NUM个不匹配的行。
man tac
:
tac - 反向连接和打印文件
答案 2 :(得分:2)
这可能是你想要的:
awk '/INFO/{f[++c]=$0} END{ if (c>0) print f[1] ORS f[c] }' messages
或:
awk '/INFO/{f[++c]=$0} END{ if (c>0) print f[1]; if (c>1) print f[c] }' messages
但没有样本输入和预期输出,这是一个猜测。
答案 3 :(得分:1)
我猜你可以使用awk:
awk '/INFO/{a[++i]=$0}END{print a[1];print a[i]}' messages
这会将每个匹配存储在一个数组中,如果匹配很多,这可能是内存消耗的问题。另一种方法是只存储第一个和最近的:
awk '/INFO/{a[++i>2?2:i]=$0}END{print a[1];print a[2]}' messages
或者正如Etan所建议的那样(谢谢):
awk '/INFO/{a=$0}a&&!i++{print}END{if(a)print a}' messages
这个的优势在于,如果没有匹配,则不会打印任何内容。