我有一个包含汽车制造商列表的文件:
$ cat cars
subaru
mercedes
porche
ferrari
audi
mercedes
BMW
ferrari
toyota
lexus
mercedes
VW
$
我想在mercedes
和ferrari
之间打印所有行,以便输出所需的输出:
mercedes
porche
ferrari
mercedes
BMW
ferrari
我的第一个想法是使用gsed -n '/mercedes/,/ferrari/p' cars
,但这显然不起作用,因为sed
逐行处理文件,而且无法知道此文件中的最后mercedes
是未跟随ferrari
。我能够用gsed -n '/mercedes/h;/^[^mercedes].*$/H;/ferrari/{g;p}' cars
完成此任务,但我发现此解决方案几乎没有问题:
1)如果存在末端标记,但不是开始标记。例如,如果我的文件中的最后mercedes
替换为ferrari
,则输出错误。
2)不能在[^mercedes]
部分使用正则表达式。例如,如果我想同时使用mercedes
和mg-motors
作为开始标记,那么我就不能使用[^m.*s]
正则表达式,因为它会匹配文字字符{{1} },m
。 .
和*
。
只有第二个标记存在时,是否有更智能的方法在s
的两个标记之间打印文本?是否应该使用sed
来解决此问题?
答案 0 :(得分:1)
您可以浏览两次文件:
ferrari
ferrari
之后和awk 'FNR==NR{if ($0~/ferrari/) {ferr++}; next}
/mercedes/{flag=1}
flag && count<ferr
/ferrari/{flag=0; count++}' file file
之前打印这些行,以防仍有一些$ awk 'FNR==NR{if ($0~/ferrari/) {ferr++}; next} /mercedes/{flag=1} flag && count<ferr; /ferrari/{flag=0; count++}' a a
mercedes
porche
ferrari
mercedes
BMW
ferrari
出现:那是:
Dim MyTable As New System.Collections.Hashtable()
Public Function GroupNumbers(ByVal LearnerID As Integer, ByVal GroupCode As String) As Integer
If MyTable Is Nothing Then
Dim MyTable As New System.Collections.Hashtable()
End If
If MyTable.ContainsKey(LearnerID) Then
If MyTable(LearnerID).ContainsKey(GroupCode) Then
Return MyTable(LearnerID)(GroupCode)
Else
MyTable(LearnerID).Add(GroupCode, MyTable(LearnerID).Count + 1)
Return MyTable(LearnerID)(GroupCode)
EndIf
Else
MyTable.Add(LearnerID, New System.Collections.Hashtable())
MyTable(LearnerID).Add(GroupCode, 1)
Return MyTable(LearnerID)(GroupCode)
End If
End Function
How to select lines between two marker patterns which may occur multiple times with awk/sed中的进一步说明。
="Group" & CStr(Code.GroupNumbers(Fields!Learner_ID.Value, Fields!Group_Code.Value))
答案 1 :(得分:1)
\s{4}
答案 2 :(得分:1)
这可能适合你(GNU sed):
sed -n '/mercedes/!d;:a;/ferrari/p;//d;N;ba' file
使用seds grep-like命令开关-n
仅在请求时打印。删除除mercedes
以外的所有行,然后打印包含ferrari
的模式空间并删除它。 Othewise附加下一行并再次测试。