【问题标题】:Matching line and remove that matching line duplicate using sed匹配行并使用 sed 删除该匹配行重复项
【发布时间】:2016-08-26 14:24:12
【问题描述】:

我有配置文件,我想要匹配特定的行,例如“server.port=5480”。保留该匹配首先删除其余匹配行。示例

server.port=5480
server.port=5480
server.port=5480
ssl.engine = "enable"
ssl.use-sslv2 = "disable"
ssl.use-sslv3 = "disable"
ssl.cipher-list = "FIPS':' +3DES':'!aNULL"
ssl.engine = "enable"
ssl.use-sslv2 = "disable"
server.port=5480
server.port=5480
server.port=5480
server.port=5480

想要的输出只有一行

server.port=5480
ssl.engine = "enable"
ssl.use-sslv2 = "disable"
ssl.use-sslv3 = "disable"
ssl.cipher-list = "FIPS':' +3DES':'!aNULL"
ssl.engine = "enable"
ssl.use-sslv2 = "disable"

使用 sed 我想要这个,还有一个不是序列行,可能是它的变体

【问题讨论】:

  • 如果您对非sed 解决方案持开放态度,您可以尝试将您的输出通过管道传输到sort -u
  • 你能举个例子吗
  • Sort -u 并不是 OP 想要的,因为它会合并整个文件并只留下唯一的条目。他只是想删除一个接一个出现多次的情况。
  • @SatheeshSivaNallathambi 可以直接使用:sort -u your_file,也可以在管道之后使用:cat your_file | sort -u。但正如 VarunMandalaparthy 所解释的那样,所有重复项都将被删除,不仅是您想要的那个,而且整个文件都会被排序。

标签: bash sed


【解决方案1】:

让我们使用awk 并打印所有不包含server.port 或它第一次出现的行:

$ awk '!(/server.port/ && c++)' file
server.port=5480
ssl.engine = "enable"
ssl.use-sslv2 = "disable"
ssl.use-sslv3 = "disable"
ssl.cipher-list = "FIPS':' +3DES':'!aNULL"
ssl.engine = "enable"
ssl.use-sslv2 = "disable"

请注意,我使用这种方法是因为我看到其他行不止一次出现。

这是如何工作的?

awk 中的真实条件触发打印整行。所以如果你说awk '1' file,所有的文件都会被打印出来。

我们在这里所做的恰恰相反:在某些情况下限制打印。这些情况是server.port 发生第二次、第三次……。
由于/server.port/ 匹配其中包含“server.port”的行,因此我们还要检查变量c 是否为正数。

  • 第一次设置时,我们有!(True && 0++),即!(True && False)!(False)True

  • 其余情况为!(True && positive++),即!(True && True)!(True)False,所以不触发打印。

【讨论】:

  • 是的,它工作正常,我想写在同一个文件上,因为我正在将此文件用于其他系统
  • @SatheeshSivaNallathambi 对于就地修改检查awk save modifications inplace
  • 感谢您的代码,我正在为几台机器运行此代码,因此我无法检查那里是否有可用的 gawk。 co有没有其他方法,我是awk的新手,你能解释一下这段代码,尤其是c++目的吗
  • @SatheeshSivaNallathambi 任何 awk 风格,你可以说 awk '...' file > tmp_file && tmp_file file。这将始终有效。关于代码本身,请参阅我的更新。
  • 我看到了"gawk -i inplace '{print $1}' file" 这一行,就像sed -i 一样好。感谢您的代码和解释,现在我也明白了
最近更新 更多