1

What I want is from the first occurrence of the delimiter to the last occurrence of the same delimiter,including everything between them,the delimiter may appear multi-times in a log file. enter image description here

sample.log

[T=iaaaaaaaaa134]:SampleClass9: 
[T=iaaaaaaaaa134]:SampleClass7: 
[T=iaaaaaaaaa134]:SampleClass3: 
[T=iaaaaaaaaa134]:SampleClass1: 
[T=i8732jddcd234]:SampleClass1: 
[T=i8732jddcd234]:SampleClass2: 
[T=i8732jddcd234]:SampleClass3: 
[T=i8732jddcd234]:SampleClass4: 
Exception:NullPointerException:
    sampte 1
    sampte 1
    sampte 1
    sampte 1
    sampte 1
    
[T=i8732jddcd234]:SampleClass00: 
[T=i8732jddcd234]:SampleClass00: 
[T=i8732jddcd234]:SampleClass00: 
[T=i8732jddcd234]:SampleClass00: 
[T=i8732jddcd234]:SampleClass00: 
Exception:NullPointerException2:
    sampte 2
    sampte 2
    sampte 2
    sampte 2
    sampte 2
[T=i8732jddcd234]:SampleClass12: 
[T=i8732jddcd234]:SampleClass32: 
[T=i8732jddcd234]:SampleClass22: 
[T=2eeeeeeeee234]:SampleClass32: 
[T=2eeeeeeeee234]:SampleClass82: 
[T=2eeeeeeeee234]:SampleClass22: 
[T=2eeeeeeeee234]:SampleClass22: 

for example: I want to extract the lines starting from the first occurrence of i8732jddcd234 (the delimiter) to the latest occurrence of i8732jddcd234 and everything between them. possibly with awk, sed, grep linux command.because this is a log file on linux server. I tried with

awk /'i8732jddcd234','i8732jddcd234'/ test.log

of course, it won't work

Wiktor Stribiżew
  • 484,719
  • 26
  • 302
  • 397
yuzhen
  • 127
  • 1
  • 8
  • 1
    @RavinderSingh123 Can you explain why this was undeleted and reopened? It seems to have very little redeeming value, and arguably a duplicate of a common FAQ. – tripleee Feb 12 '21 at 16:27
  • 1
    @tripleee, Sorry I didn't get this comment's notification(since I was not tagged properly). With respect to link which is added as a dupe doesn't looked to me exact one so I voted to open, for low quality IMHO OP has shown efforts in question so I voted to reopen, thank you. – RavinderSingh13 Feb 12 '21 at 17:12
  • 1
    It doesn't appear to be dupe of the linked question. This problem is different. – anubhava Feb 15 '21 at 16:46

4 Answers4

2

Following awk may help you on same.

awk '/i8732jddcd234/{if(!first){first=FNR};end=FNR} {a[FNR]=$0} END{for(i=first;i<=end;i++){print a[i]}}'  Input_file

Adding a non-one liner form of solution too now.

awk '
/i8732jddcd234/ {
   if (!first) {
      first = FNR
   }
   end = FNR
}
{
   a[FNR] = $0
}
END {
  for(i = first; i <= end; i++) {
     print a[i]
  }
}'  Input_file
anubhava
  • 664,788
  • 59
  • 469
  • 547
RavinderSingh13
  • 101,958
  • 9
  • 41
  • 77
1
last=$(nl sample.log | tac | awk '/i8732jddcd234/ {print $1; exit}')
sed -n "/i8732jddcd234/,${last}p" sample.log

or, with awk taking 2 passes through the file:

awk -v code=i8732jddcd234 '
    NR == FNR {
        if ($0 ~ code) {
            if (!first) first=FNR
            last=FNR
        }
        next
    } 
    first <= FNR && FNR <= last
' sample.log sample.log
glenn jackman
  • 207,528
  • 33
  • 187
  • 305
0

This might work for you (GNU sed):

sed '/i8732jddcd234/!d;:a;n;:b;//ba;$d;N;bb' file

Delete all lines till there is one containing i8732jddcd234. Print the line containing i8732jddcd234 and then check to see if the following line does too and if so repeat. Otherwise, gather up the lines until the next occurrence of i8732jddcd234 or the end-of-file, in which case the accumulated lines can be deleted.

potong
  • 47,186
  • 6
  • 43
  • 72
-1

shell only...

    #!/bin/bash

    fileLength=`wc -l dat | cut -d' ' -f1`

    firstMatch=0
    lastMatch=0

    for i in `grep -n i8732jddcd234 dat | cut -d: -f1`; do
        if [ $firstMatch == 0 ] ; then
            firstMatch=$i
        else
            lastMatch=$i
        fi
    done

    diff=$(( lastMatch - firstMatch ))
    topOfMatch=$(( fileLength - firstMatch ))

    tail --lines=$topOfMatch dat | head --lines=$diff
7 Reeds
  • 1,945
  • 2
  • 25
  • 50