我想添加一个虚拟 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
我想要的输出:
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
我有这条线,但它仅替换找到的第一个重复项:
awk '{print $0; if((getline nl) > 0){ print ($0!="IP_Remote_Address" && $0 == nl)? nl=$0"INSERT_NOT_FOUND_ABOVE" : nl }}' file.txt
我稍后可以使用 sed 将字符串替换INSERT_NOT_FOUND_ABOVE"
为:
sed '/INSERT_NOT_FOUND_ABOVE/i Address : NOT_FOUND' file.txt > new_file.txt
我唯一的问题是它无法检测所有连续的重复项;它只找到第一个。
答案1
awk
:
awk 'p==$0{print " Address : NOT_FOUND"}{p=$0}1'
一个相当幼稚的解决方案。
p==$0
IF p == 当前行- 然后打印
not found
- 然后打印
p=$0
SET p = 当前行1
: 打印
处理连续的重复行。
正如所指出的@旧金山在有问题的评论中,“最后一个IP可能也不见了,对吧?”- UPS。应该想到这一点。
所以:
awk -v e='Address : NOT_FOUND' 'p==$0{print e}{p=$0}END{if($1 ~ "IP")print e}1'
- Set
e
= 要注入的文本 p==$0
IF p == 当前行- 然后打印变量
e
- 然后打印变量
p=$0
SET p = 当前行END
打印e
当前行是否包含IP
1
: 打印
这里的错误字符串由于我们使用了两次,因此已将其添加为变量。 (并在这篇文章中为了可读性而进行了修剪)。
答案2
她是在 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
这是修改后的测试文本,带有三重错误和最后一行错误:
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
像这样运行它:
sed -Ef parse.sed infile
或者作为一句单行:
<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'
两种情况下的输出:
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 : NOT_FOUND
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
IP_Remote_Address
Address : NOT_FOUND
答案3
在其扩展正则表达式模式下使用流编辑器实用程序 sed 的 GNU 版本:
sed -Ee '
x;1d;G
${/\n\s*IP_/ba;}
/^(.*)\n\1$/{
g;:a;p;c\
Address : NOT_FOUND
b
}
$!s/\n.*//
' file
- 当前行进入保存空间,前一行进入模式空间。
- 当保持和模式空间(即上一行和当前行)之间存在匹配时,我们打印该行+未找到的行。
- 最后一行是 /IP_/ 然后我们还添加未找到的行。