![仅对文件进行部分行的 grep](https://linux22.com/image/1308894/%E4%BB%85%E5%AF%B9%E6%96%87%E4%BB%B6%E8%BF%9B%E8%A1%8C%E9%83%A8%E5%88%86%E8%A1%8C%E7%9A%84%20grep.png)
我有一个 rtf 文件,我正在像这样使用 grep
grep "Order Number" 'Extract Text Output.rtf'
结果是这样的
\b\fs28 \cf2 Fab Order Number : FAB00772450\
我希望结果只是 FAB00772450
我知道如果我使用 -o 它只会返回单词“订单号”,但这对我没有帮助
答案1
cat 'Extract Text Output.rtf' | sed -n 's/Order Number : \(.*\)\\/\1/gp'
得到的结果正是您想要的。
解释:
sed -n
抑制 sed 的默认输出s/.../.../g
搜索和替换,g:一切/全球Order Number : \(.*\)\\
查找“Order Number :
”字符串和 abackslash
并将两者之间的任何内容保存到组 1;(使用 sed 的缺点是必须转义正则表达式的分组运算符:(...)
with\(...\)
)\1
使用组 1 作为替换p
如果匹配则打印替换内容
这比使用硬编码的 awk 组($7)更加灵活和通用。
注 1:如果您的行格式如下,请使用 .*?:
\cf2 Fab Order Number : FAB00772450\ \b \cf2
这可以防止正则表达式过于贪婪,并在第一个反斜杠处停止。尚未测试 sed 是否支持 *? 和 +? 运算符,但我们希望如此。
注 2:如果你想从一行中提取多个部分,请使用多个组,在替换字符串中,你甚至可以使用格式切换它们,例如.../\2 - \1/
答案2
这对我有用:
grep "Order Number" test.txt | awk {'print $7'} | tr "\\\ " " "
输出:
FAB00772450
答案3
我想说这是一个比以前任何答案都更好、更清晰的方法:
grep -oP 'Order Number :\s*\K[^\r\n]*' 'Extract Text Output.rtf'
或者
grep -oP 'Order Number :\s*\K[A-Z0-9]*' 'Extract Text Output.rtf'
\K
丢弃到该点为止匹配的所有内容。
答案4
如果始终遵循此格式,但标记数并不总是相同,则可以通过类似
sed's/.*://'|sed's#\##'
这也会产生“FAB00772450”