我有一个包含内容的文件
x
a
x
b
x
c
我想grep最后一次出现,
x
c
当我尝试
时sed -n "/x/,/b/p" file
它会列出所有行,从x
开始到c
。
答案 0 :(得分:25)
我不确定我的问题是否正确,所以这里有一些黑暗的镜头:
打印x
的最后一次出现:
grep x file | tail -1
从第一个匹配行打印文件到结束:
awk "/x/ { flag = 1 }; flag" file
从最后一个匹配行打印文件到结尾(如果不匹配则打印所有行):
tac file | awk "!flag; /x/ { flag = 1 }; " | tac
答案 1 :(得分:3)
这可能适合你(GNU sed):
sed '/x/h;//!H;$!d;x' file
保存最后x
以及保留空间中的内容,并将其打印在文件末尾。
答案 2 :(得分:1)
不确定如何使用sed
执行此操作,但您可以尝试awk
awk '{a=a"\n"$0; if ($0 == "x"){ a=$0}} END{print a}' file
答案 3 :(得分:1)
grep -A 1 x file | tail -n 2
-A 1
告诉grep在匹配行之后打印一行
使用tail
,您将获得最后两行。
或以相反的方式:
tac fail | grep -B 1 x -m1 | tac
注意:您应确保模式足够“强”,以使其正确。即以^
开头并以$
结尾。
答案 4 :(得分:0)
POSIX vi(或 ex 或 ed),以防对某人有用
当然是在命令模式下完成
:set wrapscan
转到第一行,然后向后搜索!
1G?pattern
较慢的方式,没有 :set wrapscan
G$?pattern
说明:
G
转到最后一行
移到该行的末尾$
?
向后搜索 pattern
第一个向后匹配将与最后一个向前匹配相同
无论哪种方式,您现在都可以删除当前(匹配)之上的所有行
:1,.-1d
或
kd1G
如果同一行上有多个匹配项,您也可以使用 d0
在行删除之前删除到匹配行的开头。
POSIX awk,如在 get last line from grep search on multiple files
awk '(FNR==1)&&s{print s; s=""}/PATTERN/{s=$0}END{if(s) print s}'
答案 5 :(得分:0)
如果你想以真正可怕的单行方式执行 awk,但让 awk 更接近函数式编程范式语法,而不必跟踪最后一次出现的时间
mawk/mawk2/gawk 'BEGIN { FS = "=7713[0-9]+="; RS = "^$";
} END { print ar0[split($(0 * sub(/\n.+$/,"",$NF)), ar0, ORS)] }'
这里我使用了多个 awk 简写:
sub(/[\n.+$/, "", $NF) # trimming all extra rows after pattern
g/sub()
返回进行的替换次数,因此将其乘以 0 会强制 split()
拆分 $0
,而不是整个文件。
split()
返回数组中的项数(这是最后一个元素位置的另一种说法),所以即使我已经修剪掉了尾随的 \n
,我仍然可以直接打印 ar0[split()]
,知道 ORS 将填充缺少的尾随 \n
。
这就是为什么这段代码看起来像我试图在定义数组本身之前提取数组项,但由于所需的逻辑流,数组将在它到达时被定义<强>打印。
现在如果你想要更简单的东西,这两个也行
mawk/gawk 'BEGIN { FS="=7713[0-9]+="; RS = "^$"
} END { $NF = substr($NF, 1, index($NF, ORS));
FS = ORS; $0 = $0; print $(NF-1) }'
或
mawk/gawk '/=7713[0-9]+=/ { lst = $0 } END { print lst }'
x|c
要求来展示这些工作,无论您是需要固定字符串还是基于正则表达式的匹配。