![特定行之间的模式搜索并打印行号](https://linux22.com/image/60552/%E7%89%B9%E5%AE%9A%E8%A1%8C%E4%B9%8B%E9%97%B4%E7%9A%84%E6%A8%A1%E5%BC%8F%E6%90%9C%E7%B4%A2%E5%B9%B6%E6%89%93%E5%8D%B0%E8%A1%8C%E5%8F%B7.png)
我有一个 20 行的文件。我想搜索第 10 行和第 15 行之间的字符串,并打印该字符串以及原始文件的行号。
我努力了sed -n 10,15p file | grep -n "pattern"
上述命令的问题是, 的输出行号 10sed
将是 的行号 1 grep
。
因此,它不会打印原始文件中的行号。
答案1
当与我一起工作时,sed
我通常发现最容易持续缩小可能的结果。这就是为什么我有时会依赖!
否定运算符。删除无趣的输入通常比有针对性地选择有趣的输入更简单——至少,这是我对此事的看法。
我发现这个方法更符合sed
的默认行为 - 即在脚本末尾自动打印模式空间。对于诸如此类的简单事情,它也可以更容易地生成健壮的脚本 - 不依赖于某些实现的语法扩展来操作的脚本(如常见的sed
{functions}
)。
这就是为什么我建议你这样做:
sed '10,15!d;/pattern/!d;=' <input
...首先修剪不在第 10 行和第 15 行范围内的任何行,然后从剩余的行中修剪任何不匹配的行pattern
。如果您发现您希望将行号sed
打印在与其匹配的行相同的行上,那么paste
在这种情况下我可能会考虑。或许...
sed '10,15!d;/pattern/!d;=' <input |
paste -sd:\\n -
...这只会交替\n
用一个:
字符或另一个\n
ewline 替换输入 ewlines。
例如:
seq 150 |
sed '10,50!d;/5/!d;=' |
paste -sd:\\n -
...印刷...
15:15
25:25
35:35
45:45
50:50
答案2
这是一个awk
解决方案:
awk '10<=NR && NR<=15 && /pattern/ {print NR,$0}' file
如果我们必须使用仅有的 sed
,然后考虑:
sed -n '10,15 {/pattern/ {=;p}}' file | sed 'N;s/\n/ /'
sed 的=
命令只会在单独的行上打印行号。上面的第二个实例sed
用于组合每两行,以便行号出现在其行之前。
答案3
使用nl
:
nl file | sed -n '10,15{/pattern/p
}'