Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sed 多行匹配模式_Sed - Fatal编程技术网

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