如何在连续的重复行之间插入一行?

Jav*_*lez 5 sed awk text-processing

我想添加一个虚拟 IP 地址,但只有在找到两个连续的重复行之后。

我在 Linux 系统上工作,这是我的输入文件:

  IP_Remote_Address
     Address : 192.168.1.1
  IP_Remote_Address
     Address : 192.168.1.2
  IP_Remote_Address
     Address : 192.168.1.3
  IP_Remote_Address
  IP_Remote_Address
     Address : 192.168.1.4
  IP_Remote_Address
     Address : 192.168.1.5
  IP_Remote_Address
     Address : 192.168.1.6
  IP_Remote_Address
     Address : 192.168.1.7
  IP_Remote_Address
  IP_Remote_Address
     Address : 192.168.1.8
Run Code Online (Sandbox Code Playgroud)

我想要的输出:

  IP_Remote_Address
     Address : 192.168.1.1
  IP_Remote_Address
     Address : 192.168.1.2
  IP_Remote_Address
     Address : 192.168.1.3
  IP_Remote_Address
     Address : NOT_FOUND
  IP_Remote_Address
     Address : 192.168.1.4
  IP_Remote_Address
     Address : 192.168.1.5
  IP_Remote_Address
     Address : 192.168.1.6
  IP_Remote_Address
     Address : 192.168.1.7
  IP_Remote_Address
     Address : NOT_FOUND
  IP_Remote Address
  Address : 192.168.1.8
Run Code Online (Sandbox Code Playgroud)

我有这条线,但它只替换找到的第一个重复项:

awk '{print $0; if((getline nl) > 0){ print ($0!="IP_Remote_Address" && $0 == nl)? nl=$0"INSERT_NOT_FOUND_ABOVE" : nl }}' file.txt
Run Code Online (Sandbox Code Playgroud)

稍后我可以使用 sed 将字符串替换为INSERT_NOT_FOUND_ABOVE"

sed '/INSERT_NOT_FOUND_ABOVE/i Address : NOT_FOUND' file.txt > new_file.txt
Run Code Online (Sandbox Code Playgroud)

我唯一的问题是它无法检测到所有连续的重复项;它只找到第一个。

ibu*_*fen 13

awk

awk 'p==$0{print "     Address : NOT_FOUND"}{p=$0}1'
Run Code Online (Sandbox Code Playgroud)

一个相当幼稚的解决方案。

  • p==$0 IF p == 当前行
    • 然后打印 not found
  • p=$0 SET p = 当前行
  • 1: 打印

处理连续的重复行。


正如@san-fran在有问题的评论中所指出的,“最后一个 IP 也可能丢失了,对吧?” - UPS。应该想到的。

所以:

awk -v e='Address : NOT_FOUND' 'p==$0{print e}{p=$0}END{if($1 ~ "IP")print e}1'
Run Code Online (Sandbox Code Playgroud)
  • 设置e= 要注入的文本
  • p==$0 IF p == 当前行
    • 然后打印变量 e
  • p=$0 SET p = 当前行
  • ENDe如果当前行包含则打印IP
  • 1: 打印

这里错误字符串已作为变量添加,因为我们使用了它两次。(并在这篇文章中为可读性进行了修剪)。


Tho*_*hor 6

她是您可以在 GNU sed 中使用滑动窗口完成的一种方法:

解析.sed

# Handle last-line-error
$ { /IP/ s/$/\n   Address : NOT_FOUND/; }

# Always keep 2 lines in pattern-space
N

# If the lines are identical
/^([^\n]*)\n\1$/ { 

  # Add error text
  s/\n/\n   Address : NOT_FOUND\n/

  # Ensure we still only have 2 lines in pattern-space
  P
  s/[^\n]*\n//
}

# Print line 1 and delete it from pattern-space
P
D
Run Code Online (Sandbox Code Playgroud)

这是一个修改后的测试文本,带有三重错误和最后一行错误:

IP_Remote_Address
   Address : 192.168.1.1
IP_Remote_Address
   Address : 192.168.1.2
IP_Remote_Address
   Address : 192.168.1.3
IP_Remote_Address
IP_Remote_Address
IP_Remote_Address
IP_Remote_Address
   Address : 192.168.1.4
IP_Remote_Address
   Address : 192.168.1.5
IP_Remote_Address
   Address : 192.168.1.6
IP_Remote_Address
   Address : 192.168.1.7
IP_Remote_Address
IP_Remote_Address
   Address : 192.168.1.8
IP_Remote_Address
Run Code Online (Sandbox Code Playgroud)

像这样运行它:

sed -Ef parse.sed infile
Run Code Online (Sandbox Code Playgroud)

或者作为单线:

<infile sed -E '${/IP/ s/$/\n   Address : NOT_FOUND/};N;/^([^\n]*)\n\1$/{s/\n/\n   Address : NOT_FOUND\n/;P;s/[^\n]*\n//};P;D'
Run Code Online (Sandbox Code Playgroud)

两种情况下的输出:

sed -Ef parse.sed infile
Run Code Online (Sandbox Code Playgroud)