Print Range Only Once Per File


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Print Range Only Once Per File
# 1  
Old 07-25-2011
Print Range Only Once Per File

Scenario:

Each of several .txt files contain the following (but perhaps with some minor variations due to code version running on the devices from which the text was extracted):

Code:
<output omitted>
SWITCH1#show proc cpu hist
                                                              
    1     111111111111111     11111     11111     11111     11
    3999995555511111333336666622222666661111144444111116666633
100                                                           
 90                                                           
 80                                                           
 70                                                           
 60                                                           
 50                                                           
 40                                                           
 30                                                           
 20       *****                                               
 10 *****************************************     ************
   0....5....1....1....2....2....3....3....4....4....5....5....
             0    5    0    5    0    5    0    5    0    5    
               CPU% per second (last 60 seconds)
                                                              
    1111111111111111111111111111111121111721111111111111671111
    5384363853456143653472465347484512537703585444536337004347
100                                                           
 90                                                           
 80                                      *                    
 70                                      *               *    
 60                                      *              **    
 50                                      *              **    
 40                                      #              **    
 30                                      #              **    
 20 * *  * **  **   **  *  **  * * ** * *#* ***   * *  **#   *
 10 ##########################################################
   0....5....1....1....2....2....3....3....4....4....5....5....
             0    5    0    5    0    5    0    5    0    5    
               CPU% per minute (last 60 minutes)
              * = maximum CPU%   # = average CPU%
                                                                          
    7222227227777287222375286232282222172272262687777227223226272272227226
    0280027203063046112658409100100011990171091324474418151608247111003502
100                                                                       
 90                                                                       
 80       *    *  **    *  *     *     *  *     *  *   *                  
 70 *     *  **** **    *  **    *     *  *  *  *****  *     * *  *   *   
 60 *     *  **** **    ** **    *     *  *  * ******  *     * *  *   *  *
 50 *     *  **** **    ** **    *     *  *  * ******  *     * *  *   *  *
 40 *     *  **** **   *** **    *     *  *  * ******  *     * *  *   *  *
 30 * *   *  **** **   *** ** *  *     *  *  * ******  * *** * ** *   ** *
 20 **********************************************************************
 10 ######################################################################
   0....5....1....1....2....2....3....3....4....4....5....5....6....6....7.
             0    5    0    5    0    5    0    5    0    5    0    5    0 
                   CPU% per hour (last 72 hours)
                  * = maximum CPU%   # = average CPU%

SWITCH1#show run
Building configuration...
<output omitted>

I wanted to parse the CPU section out of each file, so I tried something like this:

Code:
awk '/^100/,/^Building/' *.txt

Unfortunately, a line beginning with "100" occurs again not too far down in the file from the first occurrence. "Building" only occurs once and thus I get my first snippet and then most of the rest of the output following the second instance of my first string.

Ideally I would end on the second "average CPU%" (not sure why there aren't three) but that looked to be a challenge for me so I thought maybe I could live with just matching on a line beginning with "Building" to end the range, and then figure out a way to not print that line or the one preceding it. Not pretty but I was trying to break the problem down into manageable pieces. At the very least, can someone please explain how to match a range one time and then print nothing further from that individual file?

As always, many thanks!

(Note: I see that spacing didn't survive the pasting process but I think the intent is still clear.)

Last edited by radoulov; 07-25-2011 at 02:28 PM.. Reason: Code tags, please!
# 2  
Old 07-25-2011
how about good old ex...
Code:
ex -s +'/^100/,/^Building/-3 p | q!' file


Last edited by shamrock; 07-25-2011 at 03:10 PM..
# 3  
Old 07-25-2011
Not familiar with ex but here's what I saw on my Mac:

$ ex -s +'/^100/,/^Building/-3 p | q!' Switch1.txt

^Z
[2]+ Stopped ex -s +'/^100/,/^Building/-3 p | q!' Switch1.txt


So basically no output until I did 'CNTL-Z'. Thanks, though!
# 4  
Old 07-25-2011
Does switching to a heredoc work...
Code:
ex -s in_file <<EOF > out_file
/^100/,/^Building/-3 p
wq
EOF

This User Gave Thanks to shamrock For This Post:
# 5  
Old 07-25-2011
Well, this certainly has promise. My out file looks pretty good:

Code:
100                                                           ^M
 90                                                           ^M
 80                                                           ^M
 70                                                           ^M
 60                                                           ^M
 50                                                           ^M
 40      *****                                                ^M
 30      *****                         *****                  ^M
 20 **********************************************************^M
 10 **********************************************************^M
   0....5....1....1....2....2....3....3....4....4....5....5....^M
             0    5    0    5    0    5    0    5    0    5    ^M
               CPU% per second (last 60 seconds)^M
                                                              ^M
    2324333323252323332323232333232323233323232323332323232333^M
    6567054485676464636365646445667575764674656365646566678765^M
100                                                           ^M
 90                                                           ^M
 80                                                           ^M
 70                                                           ^M
 60            *                                              ^M
 50    *       *                                              ^M
 40  * * *   * *    *    *     * * * * * *   *   **  * * * ***^M
 30 ***********#**********************************************^M
 20 ##########################################################^M
 10 ##########################################################^M
   0....5....1....1....2....2....3....3....4....4....5....5....^M
             0    5    0    5    0    5    0    5    0    5    ^M
               CPU% per minute (last 60 minutes)^M
              * = maximum CPU%   # = average CPU%^M
                                                                          ^M
    3333333733364333333333553333333533373343333333353333344644484447555655^M
    7788787188682777678686297797778078668826576668686789922047709892020101^M
100                                                                       ^M
 90                                                                       ^M
 80                                    *                       *          ^M
 70        *   *                       *                       *   *      ^M
 60        *   *           *           *           *       *   *   *   *  ^M
 50        *   *          **       *   *           *       * *************^M
 40 **********************************************************************^M
 30 **********************************************************************^M
 20 ######################################################################^M
 10 ######################################################################^M
   0....5....1....1....2....2....3....3....4....4....5....5....6....6....7.^M
             0    5    0    5    0    5    0    5    0    5    0    5    0 ^M
                   CPU% per hour (last 72 hours)^M
                  * = maximum CPU%   # = average CPU%^M

I'm just slowly coming up to speed on basic awk, though, and know nothing about ex or even heredocs. I was hoping to use some of what I've learned of awk to add some additional detail (such as printing the second field of the 'hostname Switch1' line from the in file or the in file name itself (which equals the hostname, actually, so it's six of one/half dozen of the other)). Is that same sort of thing possible here? Is it as easy as invoking "FILENAME" in awk?

Thank so much!

---------- Post updated at 01:04 PM ---------- Previous update was at 12:47 PM ----------

Just realized too that I don't seem to be able to do *.txt as my in file. I have to repeat this over a couple of hundred .txt files on an ongoing basis. Is there an equivalent to that with this approach?

Thanks again!

---------- Post updated at 03:06 PM ---------- Previous update was at 01:04 PM ----------

I was thinking about this over lunch. Maybe the range approach is not what I want. Maybe I want to match the first line that begins with "100" and print that line. Print every line thereafter until I reach the first line that ends with "CPU%." Print that line too. Continue to print every line until I once again find a line that ends with "CPU%." Print that line and exit, move to next file. I wonder if that's actually simpler than trying to solve this with the range function?

---------- Post updated at 05:59 PM ---------- Previous update was at 03:06 PM ----------

So the simplest - and in retrospect best - solution was simply to print the range in between the two 'show' commands in the input files:

Code:
	ls *.txt | xargs awk '/show proc cpu hist/,/show run/'

All that I need to do now is how to figure out how to print everything in between those two lines but not including those two lines. And I need to get the host or file name printed for each iteration (which I'm pretty confident I can figure out).

---------- Post updated at 07:30 PM ---------- Previous update was at 05:59 PM ----------

OK, I just need one final piece. I realize that this is probably very inelegant, but it almost works and I've once again lost an entire day to a single script!

Code:
#!/bin/ksh
ls *.txt | xargs awk '
  		  
    FILENAME != last {
    fn = FILENAME;
    gsub( ".txt", "", fn );
    last = FILENAME;
    }
        
    /show proc cpu hist/,/show run/ { print $0 };
  		
' | awk '!/show proc cpu hist/&&!/show run/' > "CPU History"

The above includes a piece given to me by agama yesterday to strip off the ".txt" extension from FILENAME. However, I haven't been able to figure out how to use what's left in the way that I want. Prior to each block of CPU history, I'd like to print "FILENAME:" beforehand. In yesterdays' case, I was building a .csv, so I wanted the filename on every single line of output. In this case I'm not building a CSV and will import the text directly into a report. So I'd like to figure out how to print the filename plus ":" once and then the CPU history block. The closest I've come was to actually awk out $2 of 'hostname Switch1' but that comes in the input file after the CPU history block, so it was printing below instead of above. And for some reason my ":" was actually printing on a new line below the hostname?? Is this more difficult than it sounds or should I be able to accomplish this easily?

Thanks.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

Advise on how to print range of lines above and below a number?

Hi, I have attached an output file which is some kind of database file mapping. It is basically like an allocation mapping of a tablespace and its datafile/s. The output is generated by the SQL script that I found from 401 Authorization Required Excerpts of the file are as below: ... (2 Replies)
Discussion started by: newbie_01
2 Replies

2. Shell Programming and Scripting

awk to print out lines that do not fall between range in file

In the awk below I am trying to print out those lines in file2 that are no between $2 and $3 in file1. Both files are tab-delimeted and I think it's close but currently it is printeing out the matches. The --- are not part of the files they are just to show what lines match or fall into the range... (6 Replies)
Discussion started by: cmccabe
6 Replies

3. UNIX for Dummies Questions & Answers

How to print specific range using awk?

I want to print specific range of rows and then its columns using awk command. lets say if a file contain 15 line then i need to print line 5 to 9. awk '{print;for( NR>=5&&NR<=9); do; print "<tr>\n<td>"$1"</td><td>"$2"</td><td>"$3"</td>\n</tr" done}' xyz.csv not sure what's wrong... (9 Replies)
Discussion started by: amyt1234
9 Replies

4. Shell Programming and Scripting

Print range of numbers

Hi I am getting an argument which specifies the range of numbers. eg: 7-15 Is there a way that i can easily (avoiding loop) print the range of number between and including the specified above. The above example should translate to 7,8,9,10,11,12,13,14,15 (3 Replies)
Discussion started by: tostay2003
3 Replies

5. Shell Programming and Scripting

awk to print range of fields

Hi file.in and file.out are in csv format. the code I have now is, cat file.in | awk -F"," '!($1$2$3$4$5$6$7$8 in a){a;print $0}' > file.out Here, I am printing entire line using $0. however, I want to print $1 to $150 and it should be in csv format. Cut -d is not good in performace.... (3 Replies)
Discussion started by: krishnix
3 Replies

6. Shell Programming and Scripting

How to print first matching range in awk?

following is input - <Schema> <schema_name>admin</schema_name> <Version>1.1</Version> <schema_name>admin</schema_name> <Version>1.2</Version> </Schema> ... (12 Replies)
Discussion started by: thearpit
12 Replies

7. Shell Programming and Scripting

Print pattern range to a new file

Hi Everyone! I really appreciate all of your help, I'm learning so much, can't wait until I get good enough to start answering questions! I have a problem ... from one large file, I'd like to create multiple new files for each pattern block beginning with /^ISA/ ending with /^IEA/ ... (2 Replies)
Discussion started by: verge
2 Replies

8. Shell Programming and Scripting

How to print range of a line?

Hi , I have a file content like following. In few lines I have fields with '"' and in few not. "Country" character varying(150), "Region" character varying(60), "Total Page Requests" numeric, "Pages Served" numeric, "Ad request" numeric, Ads Served ... (5 Replies)
Discussion started by: sussus2326
5 Replies

9. Shell Programming and Scripting

print range between two patterns if it contains a pattern within the range

I want to print between the range two patterns if a particular pattern is present in between the two patterns. I am new to Unix. Any help would be greatly appreciated. e.g. Pattern1 Bombay Calcutta Delhi Pattern2 Pattern1 Patna Madras Gwalior Delhi Pattern2 Pattern1... (2 Replies)
Discussion started by: joyan321
2 Replies

10. UNIX for Dummies Questions & Answers

Need to print file names in a certain date range using ls

I need to list only file names of a specific date from the command ls -lt. :confused: (2 Replies)
Discussion started by: Shamwari
2 Replies
Login or Register to Ask a Question