Reputation: 127
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.
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
Upvotes: 1
Views: 434
Reputation: 58401
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.
Upvotes: 0
Reputation: 2539
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
Upvotes: -1
Reputation: 133508
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
Upvotes: 2
Reputation: 246807
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
Upvotes: 1