我有以下sed命令,用于获取其中包含<interface>
XML的日志的整个块,该日志将被打印到txt文件中:
sed -n '/(StartingExpression)/{:start /<\/Interface>/!{N;b start};/(SomeValueInTheXML)"/p}' *.log > File.txt
问题是我有一些动态值(时间戳)总是比(StartingExpression)
高出4行...有没有办法打印像:
line of (StartingExpression) -4
我发现了这个问题: search (e.g. awk, grep, sed) for string, then look for X lines above and another string below但解决方案并不是很清楚:\
感谢您的帮助。
另外,如果有人有很好的资源来学习sed,我会很感激,如果你发布它:)
按要求编辑:
one
two
1/1/2015
line 1
12345
(StartingExpression)
<Interface>
<A>
Name=Andy
</A>
</Interface>
three
four
1/1/2015
line 1
12345
(StartingExpression)
<Interface>
<A>
Name=John
</A>
</Interface>
hello
world
我想从1/1/2015
打印((StartingExpression)
以上3行 - 这可以是动态的,因为它是一个日期)直到</Interface>
编辑:我忘了提及,这些界面可能有多个实例......你如何确保只打印Name=Andy
的那个?
file.txt的:
1/1/2015
line 1
12345
(StartingExpression)
<Interface>
<A>
Name=Andy
</A>
</Interface>
答案 0 :(得分:1)
这个awk
成语将在模式前面打印n行。
$awk -v n="$plines" '{a[p]=$0; p=(p+1)%n} /pattern/{for(i=p;i<p+n;i++) print a[i%n]}' file
例如
$awk -v n=5 '{a[p]=$0; p=(p+1)%n} /20/{for(i=p;i<p+n;i++) print a[i%n]}' <(seq 10 99)
16
17
18
19
20
更新其他逻辑。
您也可以轻松地在模式匹配后合并打印。此脚本将打印之前的行;现在比赛结束后直到结束标签。
$ awk -v n=4 ' {a[p]=$0; p=(p+1)%n}
/(StartingExpression)/{for(i=p;i<p+n-1;i++) print a[i%n];f=1}
f{print}
/\/Interface/{exit}' file
1/1/2015
line 1
12345
(StartingExpression)
<Interface>
<A>
</A>
</Interface>
更新:根据属性值过滤
此时更容易通过另一个脚本而不是重写它。用f = 0替换出口,第一个脚本将输出所有匹配的记录,并在第二个脚本中过滤感兴趣的记录。
$ awk -v n=4 ' {a[p]=$0; p=(p+1)%n}
/(StartingExpression)/{for(i=p;i<p+n-1;i++) print a[i%n];f=1}
f{print}
/\/Interface/{f=0}' file
| awk 'BEGIN{ORS=RS="</Interface>\n"}
/Name=Andy/'
1/1/2015
line 1
12345
(StartingExpression)
<Interface>
<A>
Name=Andy
</A>
</Interface>
答案 1 :(得分:0)
如果您的grep版本支持-A和-B,并且您的文件是使用固定行创建的,则可以使用
grep -A2 -B6 "Name=Andy" request
使用你的知识可以帮助你做出以下命令:
echo "/(StartingExpression)/-3,/<.Interface>/ p" | ed -s request
我使用.
作为斜杠,我不想逃避角色。只有当安迪成为第一个名字时,这才有效。
让安迪在其他地方工作变得更加棘手:
rm /tmp/andy
echo "/Name=Andy/
?(StartingExpression)
-3,/<.Interface>/ w /tmp/andy" | ed -s request 2>&1 >/dev/null
cat /tmp/andy
rm /tmp/andy