One can use sed and regular expressions to find chunks of text that span multiple line.
To look for ranges of lines in other words with sed:
sed '/range-start-line-regex/,/range-end-line-regex/ other commands' $file
Example
I'm a Java developer so the example will be from Java world. I was on a support case and we were trying to debug a problem a customer had. As part of the debugging process we've requested the customer to take a number of thread dumps.
The thread dumps we've received contain hundreds of threads. If you don't know, that's how a thread in a thread dump looks like:
"hz.hazelcast.cached.thread-15" #368 prio=5 os_prio=0 tid=0x00007f0634cbb800 nid=0x3fd1 waiting on condition [0x00007f05aa0dd000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x0000000640002c60> (a java.util.concurrent.SynchronousQueue$TransferStack)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1073)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
at com.hazelcast.util.executor.HazelcastManagedThread.executeRun(HazelcastManagedThread.java:76)
at com.hazelcast.util.executor.HazelcastManagedThread.run(HazelcastManagedThread.java:92)
Locked ownable synchronizers:
- None
I was interested in threads that look like this:
"spring-startup" #65 daemon prio=5 os_prio=0 tid=0x00007f0706f68800 nid=0x624 runnable [0x00007f063911a000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
at sun.nio.ch.IOUtil.read(IOUtil.java:197)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380)
- locked <0x00000006d99b7140> (a java.lang.Object)
................................
at java.lang.Thread.run(Thread.java:748)
In order to find those chunks of text in dozen of files with thousands lines of thread stacks I used sed:
for file in $(find .. -name "threads.*.txt"); do \
sed -En '/^"spring-startup".*$/,/^[[:space:]]*$/ p' $file> $(basename $file);
done
Here I go through files and for each file I ask sed
to find ranges of lines
which start with line that matches ^"spring-startup".*$
and ends with line
that matches ^[[:space:]]*$
and print them: p
As result I have bunch of files that contain only stack traces for spring-startup
threads.