Sed 多行匹配模式
我有一个文件如下Sed 多行匹配模式,sed,Sed,我有一个文件如下 NAME(BOLIVIA) TYPE(SA) APPLIC(Java) IP(192.70.xxx.xx) NAME(BOLIVIA) TYPE(SA) APPLIC(Java) IP(192.71.xxx.xx) 我正在尝试使用sed提取NAME和IP值: cat file1 | sed ':a N $!ba s/\n/ /g' | sed
NAME(BOLIVIA) TYPE(SA)
APPLIC(Java) IP(192.70.xxx.xx)
NAME(BOLIVIA) TYPE(SA)
APPLIC(Java) IP(192.71.xxx.xx)
我正在尝试使用sed提取NAME和IP值:
cat file1 |
sed ':a
N
$!ba
s/\n/ /g' | sed -n 's/.*\(NAME(BOLI...)\).*\(IP(.*)\).*/\1 \2/p'
但是,我只得到了输出:
NAME(BOLIVIA) IP(192.71.xxx.xx)
我想要的是:
NAME(BOLIVIA) IP(192.70.xxx.xx)
NAME(BOLIVIA) IP(192.71.xxx.xx)
如果有人能告诉我我错过了什么,我将不胜感激
TIA脚本中的问题是如何使用
*
以贪婪
的方式匹配
因此,您只有第一个名称(BOLI…
和最后一个IP(.*)
如果您可以使用python:
#!/bin/bash
python -c '
import re, sys
for ar in re.findall(r"(NAME\(BOLI.*?\)).*?(IP\(.*?\))", sys.stdin.read(), re.DOTALL):
print(*ar)
' < input-file
#/bin/bash
python-c'
输入re,sys
对于re.findall(r)(名称\(BOLI.*?\).*(IP \(.*?))”、sys.stdin.read()、re.DOTALL中的ar:
打印(*ar)
“<输入文件
如果您对awk
没有问题,请尝试以下内容。用link编写并测试
仅显示样品
awk '
match($0,/^NAME\([^)]*/){
name=substr($0,RSTART+5,RLENGTH-5)
next
}
match($0,/IP\([^)]*/){
print name,substr($0,RSTART+3,RLENGTH-3)
name=""
}
' Input_file
您的第一个sed
命令将文件重新格式化为一个长行。您可以使用tr-d“\n”
,但这不是问题所在。
问题在第二部分,贪婪者在找到最后一个匹配项之前尽可能多地吃东西
您的解决方案可以用丑陋的
# Do not use this:
sed -zn 's/[^\n]*\(NAME(BOLI...)\)[^\n]*\n[^\n]*\(IP([^)]*)\)[^\n]*/\1 \2/gp' file1
可能的解决办法:
cat file1 | paste -d " " - - | sed -n 's/.*\(NAME(BOLI...)\).*\(IP(.*)\).*/\1 \2/p'
# or
grep -Eo "(NAME\(BOLI...\)|IP\(.*\))" file1 | paste -d " " - -
# or
printf "%s %s\n" $(grep -Eo "(NAME\(BOLI...\)|IP\(.*\))" file1)
这可能适用于您(GNU-sed):
如果一行包含NAME
,而下一行包含IP
,则删除中间的所有内容并打印结果。另一个较短的awk
:
awk'$1~/^NAME/{nm=$1}$2~/^IP/{print nm,$2}文件
姓名(玻利维亚)IP(192.70.xxx.xx)
姓名(玻利维亚)IP(192.71.xxx.xx)
awk
对于多条生产线的加工条件来说是一个不错的选择。您的解决方案比其他输入(不同的第一个/最后一个字段)失败的awk'/NAME\(BOLIV/{get_ip=1;printf$1;next};get_ip==1{print”“$NF}
)要好。嗯,很好,我没有把我的awk
作为答案发布。{print”“$NF}
应该是{print”“$NF;get_ip=0;}
。感谢RavinderSingh13的解决方案。也感谢您对ideone的引用。在您提到之前从未见过该网站!太棒了!感谢您展示了多种给这只猫剥皮的方法!
sed -n '/NAME/{N;/IP/s/\s.*\s/ /p}' file