我有一个包含多行文本的 bash 变量,其中包括 IP 地址,我需要在同一行中最后一个 IP 地址出现之前删除“所有内容”。
这个:
43.12.40.53 [email protected]
archery-666.foobar.com 66.77.11.44 data test@example
55.32.39.153 [email protected]
5.113.30.37 dummy
89-109-22-006.static.example.com.br 89.109.22.6 [email protected]
68.28.15.55 68.28.15.55 another
应转化为:
43.12.40.53 [email protected]
66.77.11.44 data test@example
55.32.39.153 [email protected]
5.113.30.37 dummy
89.109.22.6 [email protected]
68.28.15.55 another
阅读这篇文章如何从一行中删除一个模式之前的所有内容以及另一个模式之后的所有内容?我试过了:
var=$(sed 's/^.*\(([0-9]{1,3}[\.]){3}[0-9]{1,3}\).*$/\1/' <<< "$var")
但它不起作用。
几个问题:
您正在混合 BRE 和 ERE(例如
\(
与(
分组相比)如果您希望结果包含 IP 之后的所有内容,您
.*
最后需要在捕获组内^.*
开头将贪婪地消耗尽可能多的字符 - 包括除一个前导 IP 数字之外的所有字符此外,
.
不需要在里面逃跑[]
——尽管这不会破坏任何东西。我不确定处理(3)的正确方法,
sed
其中(不像perl
说)没有非贪婪修饰符。添加一个词边界锚\b
似乎有效,但感觉很脆弱所以要么(BRE)
或 (ERE)
您已经正确地转义了第一个括号,但不是第二个,也不是
{}
也需要转义的。此外,您将所有内容都匹配到.*$
不需要的行 ( ) 的末尾。使用你的正则表达式,这会做你想要的:但这仍然比必要的复杂。比如你不需要
[\.]
,一个简单\.
的就够了。您可以使用该-E
标志来启用扩展正则表达式并将您的语法简化为:但是,正如 steeldriver 指出的那样,您的领先优势
.*
可能比您预期的要多,因此在 perl 中执行整个操作会更安全: