如果存在第二个标记,则使用sed在两个标记之间打印文本

时间:2015-11-25 11:19:22

标签: awk sed pattern-matching

我有一个包含汽车制造商列表的文件:

$ cat cars
subaru
mercedes
porche
ferrari
audi
mercedes
BMW
ferrari
toyota
lexus
mercedes
VW
$ 

我想在mercedesferrari之间打印所有行,以便输出所需的输出:

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]部分使用正则表达式。例如,如果我想同时使用mercedesmg-motors作为开始标记,那么我就不能使用[^m.*s]正则表达式,因为它会匹配文字字符{{1} },m.*

只有第二个标记存在时,是否有更智能的方法在s的两个标记之间打印文本?是否应该使用sed来解决此问题?

3 个答案:

答案 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附加下一行并再次测试。