【问题标题】:Grep an IP with exact match and match between random stringGrep 一个完全匹配的 IP 和随机字符串之间的匹配
【发布时间】:2021-02-13 07:48:34
【问题描述】:

我正在尝试显示以下包含 IP 地址的输入文件。我想显示字符串之间的完全匹配,如示例所示,但似乎没有成功。这里的演示是一个名为 input.txt 的文本文件中的示例数据:

1. IP [1.1.1.1] 
2. IP [1.1.1.11] 
3. IP [1.1.1.115]
4. IP "1.1.1.1 " 
5. IP "1.1.1.11 "
6. IP "1.1.1.115"
7. IP U*@K1.1.1.1-I(M@ 
8. IP *JJ1.1.1.11()
9. IP *J@K1.1.1.115U*@ 
10. IP U#@I1.1.1.19lds

那么,假设我要找到这个IP:1.1.1.1,我会写如下代码:

grep -w '1.1.1.1' input.txt

这样我得到了以下输出:

1. IP [1.1.1.1]
4. IP "1.1.1.1 "

但预期的输出是,第 7 行也应该显示,因为它包含一个随机字符串之间的1.1.1.1 的 IP。所以预期的输出应该是这样的:

1. IP [1.1.1.1]
4. IP "1.1.1.1 "
7. IP U*@K1.1.1.1-I(M@

现在假设我想找到这个字符串:1.1.1:

grep -w '1.1.1' input.txt

我得到以下输出:

1. IP [1.1.1.1]
2. IP [1.1.1.11]
3. IP [1.1.1.115]
4. IP "1.1.1.1 "
5. IP "1.1.1.11 "
6. IP "1.1.1.115"
7. IP U*@K1.1.1.1-I(M@

预期的输出是,它不应该返回任何内容,因为整个字符串 1.1.1 不在 input.txt 内。

grep 能做到这一点吗?

【问题讨论】:

  • 是的,它只是从第一行到第七行显示相同的意外输出。 @blurfus
  • grep "\<1.1.1\>" input.txt 也输出相同的结果第 1 行直到第 7 行
  • 我对这个问题感到困惑。您希望 IP U*@K1.1.1.1-I(M@1.1.1.1 匹配,即使它不完全是一个单词(即 K1),但是您希望没有任何东西与 1.1.1 匹配相同的输入? - 同样的K1 场景呢?
  • 如果输入有这个:1.1.1-2 它应该显示,因为 1.1.1 在那里。但如果输出是这个1.1.1.3,它不应该显示。简而言之,如果在该字符串 1.1.1 之后出现一个点或一个数字,则它是无效的。也许这就是他的意思。
  • @blurfus IP 应该在随机字符串之间匹配。随机字符串之间的有效 IP 示例是 UIO@#J1.1.1.1J@*JKJHH9.1.3.2{}@POxjk29)192.111.22.3p 或在真实日志文件中:http://1.2.3.4/test?okhttp://local/match.php?&abc=1.2.2.2&a

标签: string bash grep


【解决方案1】:

简化并更加明确。

$: grep '[^.0-9]1.1.1.1[^.0-9]' txt
1. IP [1.1.1.1]
4. IP "1.1.1.1 "
7. IP U*@K1.1.1.1-I(M@

不过,这仍然存在缺陷 - 将另一条记录添加到您的测试数据中。

$: grep '[^.0-9]1.1.1.1[^.0-9]' txt
1. IP [1.1.1.1]
4. IP "1.1.1.1 "
7. IP U*@K1.1.1.1-I(M@
11. IP [1a1b1c1]

然后试试这个:

$: grep '[^.0-9]1\.1\.1\.1[^.0-9]' txt
1. IP [1.1.1.1]
4. IP "1.1.1.1 "
7. IP U*@K1.1.1.1-I(M@

这仍然没有考虑到 IP 在线路末端的可能性,所以如果有可能的话,

$: grep -E '(^|[^.0-9])1\.1\.1\.1([^.0-9]|$)' txt
1. IP [1.1.1.1]
4. IP "1.1.1.1 "
7. IP U*@K1.1.1.1-I(M@
12. IP 1.1.1.1

如果 IP 作为变量出现,您可以在适当的位置引用它。

$: ip=1.1.1.1
$: echo "grep -E '(^|[^.0-9])${ip//./\\.}([^.0-9]|$)'"
grep -E '(^|[^.0-9])1\.1\.1\.1([^.0-9]|$)'
$: grep -E "(^|[^.0-9])${ip//./\\.}([^.0-9]|$)" txt
1. IP [1.1.1.1]
4. IP "1.1.1.1 "
7. IP U*@K1.1.1.1-I(M@
12. IP 1.1.1.1

如果您的模式变得复杂,这可能会出现问题,但在这里可以正常工作。

【讨论】:

  • 谢谢,我会添加更多的输入和测试。赞成您的回答。
  • 我喜欢这个答案,但是如果输入是可变的,例如 ip="1.2.3.2" 那么我们将如何修改这个变量以进行这样的转义呢? grep -E '(^|[^.0-9])${ip}([^.0-9]|$)' txt ?它适用于变量吗?
【解决方案2】:
$ grep '[^[:digit:].]1.1.1.1[^[:digit:].]' file
1. IP [1.1.1.1]
4. IP "1.1.1.1 "
7. IP U*@K1.1.1.1-I(M@

$ grep '[^[:digit:].]1.1.1[^[:digit:].]' file
$

【讨论】:

  • 谢谢,我会添加更多的输入和测试。赞成您的回答。
  • 我回到了这个解决方案,我认为这个解决方案工作得更好,包括 ipv6。进行更多测试。
  • 但如果 ipv6 以 240e:00f7:4f01:000c:0000:0000:0000:0003:ee 之类的字母结尾或开头则不起作用
猜你喜欢
  • 2011-09-16
  • 2023-01-30
  • 1970-01-01
  • 2010-12-03
  • 2012-03-26
  • 1970-01-01
  • 1970-01-01
  • 2016-07-19
  • 2013-05-21
相关资源
最近更新 更多