Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

printf awk sed to retrieve data

Status
Not open for further replies.

Triton46

Programmer
Jan 9, 2002
33
US
I have a file that looks like:

procs memory page disk faults cpu
r b w swap free re mf pi po fr de sr m0 m1 m3 m4 in sy cs us sy id
0 0 0 1888 776 4 109 65 6 2277 0 3771 0 0 0 0 625 2371 1162 16 12 72

It was built from vmstat for Oracle. Out of this file I want to grab only certain parts to be inserted into a table. I have tried the following:

while read RUNQUEPAGE_IN PAGE_OUT USER_CPU SYSTEM_CPUIDLE_CPU WAIT_CPU
do
cat /tmp/msg$$|sed 1,4d | awk '{ printf("%s %s %s %s %s %s %s\n", $1, $8, $9, $14, $15, $16, $17)}'

Do I need a '%s' for every column in the file? Is there a simple way to retrieve certain columns from this file?
 
I'm not exactly sure what you are trying to do, but replacing your printf with the following print statement may be slightly simpler.
Code:
print $1 " " $8 " " $9 " " $14 " " $15 " " $16 " " $17
CaKiwi
 
I'm trying to grab the value at 1, 8, 9, etc.

I'm using this script from a DBA tuning sight:


This part confuses me as I am not a Unix guru. Even the way he defines it does not seem to work (as the man pages define it). The output I get from running that (by using echo) only shows the first few values then everything is dropped into $17.

I want to grab specific values so I can populate a table. So from my above example, how would I grab 109 then 65 then 625 then etc. Does that help?
 
If you use printf() then yes you do need the %s's. But if you use just print, then no.
e.g.
cat /tmp/msg$$ | sed 1,4d | awk '{
print $1 $8 $9 $14 $15 $16 $17 }'

In awk you dont need to use a backslash to continue to the next line as you did in your example. Hope this helps.
 
Yeah, but this is what I get weather I use printf or print

,
devcix


memory
page


faults cpu

The spaces represent nulls but you can see what it is grabbing. It does this three times for the different lines.


,
devcix


b
w


free re mf pi po fr de sr m0 m1 m3 m4 in sy cs us sy id

Then line three:

,
devcix


0
0


5592 4 114 66 7 2257 0 3805 0 0 0 0 632 2650 1214 18 12 70

(ignore the values this is from a live run but it shows what I am receiving from the command.

 


cat /tmp/msg$$ | sed 1,4d | nawk -F "[ ][ ]*" '{ print $1 $8 $9 $14 $15 $16 $17 }'
 
Triton,
regarding your second message, dated may 30...

first of all, the command sed '1,4d' will delete the first four lines in your three-line file. So should be sed '1,2d'.

by default, awk uses a whitespace (tab or space) as the field separator. So consider the following line of text...

0 0 0 1888 776 4 109 65 6 2277 0 3771 0 0 0 0 625



to get 109, then 65, then 625 etc. you would use

awk '{print $7 " " $8 " " $17}'

tip-->the very last field can also be referenced by $NF.

I'm not sure if the while / do statement is needed in your example if you're needing to do what I think your trying to do. I think all that you need is..

cat /tmp/msg$$ | sed 1,2d | awk '{
print $7 " " $8 " " $17}' > newfile
newfile is the file that will contain the results.(optional)

Hope this helps ya.
 
Let me past the entire while loop:

while read RUNQUEPAGE_IN PAGE_OUT USER_CPU SYSTEM_CPUIDLE_CPU WAIT_CPU
do
echo 'start second loop'
cat /tmp/msg$$ | sed 1,4d | nawk -F "[ ][ ]*" '{ print $1 $8 $9 $14 $15 $16 $17 }'
#$ORACLE_HOME/bin/sqlplus xxx/xxx@xxx<<EOF
# insert into mon_vmstats values (
# sysdate,
echo $SAMPLE_TIME,
echo $SERVER_NAME
echo $RUNQUE
echo $PAGE_IN
echo $PAGE_OUT
echo $USER_CPU
echo $SYSTEM_CPU
echo $IDLE_CPU
echo $WAIT_CPU

by putting in the other command (nawk) I still get the same results.

30,
devcix
null
null
1
0
null
null
61504 13 26 0 3 4171 0 2350 1 0 0 0 1156 4334 3634 48 26 25
 
linmatty,

I need the loop to do an insert into from the file to a table. That part works. :)

But this sed/awk/print/printf business is spitting out the wrong stuff.
 


sed -e '1,2d' /tmp/msg* | nawk -F '[ ][ ]*' ' {printf(&quot;%d %d %d %d %d %d %d\n&quot;, $1, $8, $9, $14, $15, $16, $17)}'
 
while read name1 name2 name3
do
echo 'start second loop'
cat /tmp/msg$$ | sed 1,2d | awk '{print $7 &quot; &quot; $8 &quot; &quot; $17}'
echo $name1
echo $name2
echo $name3

Here is the latest output:

114 67 633
2 1453 747
procs
memory
page disk faults cpu
 


or better YET [to get rid of the 'leading' spaces:

sed -e '1,2d' -e 's/^[ ]*//g' /tmp/msg* | nawk -F '[ ][ ]*' ' {printf(&quot;%d %d %d %d %d %d %d\n&quot;, $1, $8, $9, $14, $15, $16, $17)}'
 
Getting closer.

The latest results:
0 114 66
0 0 0
0 0 0
0 114 66
0 0 0
0 0 0
0 114 66
0 0 0
0 0 0
0 114 67
0 0 0
0 0 0
0 114 67
0 0 0
0 0 0
0 114 67
0 0 0
0 0 0
0 114 67
0 0 0
0 0 0
0 114 67
0 0 0
0 0 0
0 114 67
0 0 0
0 0 0
0 114 67
0 0 0
0 0 0
0 114 67
0 0 0
3
0
0 10055096 60800 1 0 0 3 2188 0 3153 0 0 0 0 790 14688 4110 74 24 1

I'm not sure why it keeps forcing everything onto the end or why it repeated so often for only three columns of information. All I am expecting would be (and this is not accurate to the data):

0
114
67

 
question, your input file, it is a three line file? That's what you stated in your original message.

If that's the case, then the cat/sed/awk stuff will never produce any output because the sed 1,4d command deletes all of the lines before it's piped into awk. Try sed '1,2d'

In your output, it looks like the echo statements are indeed working. (9 echo staements, 9 output lines.) But no results from cat/sed/awk because sed '1,4' deleted all lines.

If I'm not on the right page here, I apologize. I know nothing about oracle.

 
sample msg file:

procs memory page disk faults cpu
r b w swap free re mf pi po fr de sr m0 m1 m3 m4 in sy cs us sy id
0 0 0 18288 5744 4 114 67 7 2265 0 3809 0 0 0 0 633 2656 1218 18 12 70

*note there are only three rows, the one starting with procs and the one starting with r and the one starting with 0.
 
linmatty,

It really has nothing to do with oracle, I am just reading in some server stats from a file that is updated constantly on the oracle server. The file is three rows long with several 'columns' of data on server statistics.

The last run I used this script:
while read name1 name2 name3
do
echo 'start second loop'
sed -e '1,2d' -e 's/^[ ]*//g' /tmp/msg* | nawk -F '[ ][ ]*' ' {printf(&quot;%d %d %d\n&quot;, $15, $16, $17)}'
echo $name1
echo $name2
echo $name3

And received this output:
0 0 632
0 0 0
0 0 0
0 0 632
0 0 0
0 0 0
0 0 632
0 0 0
0 0 0
0 0 633
0 0 0
0 0 0
0 0 633
0 0 0
0 0 0
0 0 633
0 0 0
0 0 0
0 0 633
0 0 0
0 0 0
0 0 633
0 0 0
0 0 0
0 0 633
0 0 0
0 0 0
0 0 633
0 0 0
0 0 0
0 0 633
0 0 0
0 0 0
0 0 633
0 0 500
0
0
0 21976 5768 4 114 67 7 2265 0 3809 0 0 0 0 633 2659 1220 18 12 70

I don't see why it keeps repeating so many times then at the end the 632 changes to 633 and 0 changes to 500. Then it spits out the whole line three from the file.
 


Running:

sed -e '1,2d' -e 's/^[ ]*//g' /tmp/sample.txt | nawk -F '[ ][ ]*' ' {printf(&quot;%d %d %d %d %d %d %d\n&quot;, $1, $8, $9, $14, $15, $16, $17)}'

on a '/tmp/sample.txt' [as posted], produces:

0 67 7 0 0 0 633


Is that something you want?

NOTE: make sure your 'sample' file has columns separated ONLY by 'space(s)' and there are no other chars separating columns [no control chars, no TABS]. If fields can be TABs as well use the folowing '-F' spec for nawk:

-F '([ ][ ]*)|[\t]'

vlad
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top