When parse result of lsof command, use awk

This is a discussion on When parse result of lsof command, use awk within the awk forums in Programming Languages category; lsof | awk '{ print $1 "\t" $7 "\t" $9 }' Through such commands Select the field to make the output as shown below. [process, file size, filename] ifdcd 3287239193 /home0031/ICFS/0000000000000000900/filename.sh but if filename field includes whitespaces charactor, ex) "/home0031/ ICFS/0000000000000000900/filen ame.sh" it will be shown below, ifdcd 3287239193 /home0031/ICFS/0000000000000000900/filen How do you resolve them? I was try change field seperator to Tab charactor, but it was not work. ---------------------------------------------------------- I'm sorry that i cannot give you a full detail of questions because of my poor english. I'm so appreciate your good answers in news group....

Go Back   Application Development Forum > Programming Languages > awk

Object Mix

Register FAQ Calendar Search Today's Posts Mark Forums Read
  #1  
Old 08-01-2008, 01:28 AM
crazytazo
Guest
 
Default When parse result of lsof command, use awk


lsof | awk '{ print $1 "\t" $7 "\t" $9 }'

Through such commands
Select the field to make the output as shown below.

[process, file size, filename]
ifdcd 3287239193 /home0031/ICFS/0000000000000000900/filename.sh


but if filename field includes whitespaces charactor, ex) "/home0031/
ICFS/0000000000000000900/filen ame.sh"
it will be shown below,

ifdcd 3287239193 /home0031/ICFS/0000000000000000900/filen


How do you resolve them?

I was try change field seperator to Tab charactor, but it was not
work.

----------------------------------------------------------
I'm sorry that i cannot give you a full detail of questions because of
my poor english.

I'm so appreciate your good answers in news group.

Reply With Quote
  #2  
Old 08-01-2008, 02:04 AM
Grant
Guest
 
Default Re: When parse result of lsof command, use awk

On Thu, 31 Jul 2008 22:28:11 -0700 (PDT), crazytazo <crazytazo@gmail.com> wrote:

>
>lsof | awk '{ print $1 "\t" $7 "\t" $9 }'
>
>Through such commands
>Select the field to make the output as shown below.
>
>[process, file size, filename]
>ifdcd 3287239193 /home0031/ICFS/0000000000000000900/filename.sh
>
>
>but if filename field includes whitespaces charactor, ex) "/home0031/
>ICFS/0000000000000000900/filen ame.sh"
>it will be shown below,
>
>ifdcd 3287239193 /home0031/ICFS/0000000000000000900/filen
>
>
>How do you resolve them?


How about:

$ lsof | awk '{ printf $1 "\t" $7 "\t";for(i=9;i<=NF;i++)printf $i" ";print""}'
....
lsof 736 /home/common
lsof 432 /
lsof 102528 /usr/bin/lsof
lsof 0 (stat: No such file or directory)
lsof 178476 /usr/lib/locale/en_US/LC_CTYPE
lsof 1441201 /lib/tls/libc-2.3.6.so
lsof 104536 /lib/ld-2.3.6.so
lsof 149806
lsof 149807

This works here on linux 'cos $9 is last field

Grant.
--
http://bugsplatter.id.au/
Reply With Quote
  #3  
Old 08-01-2008, 02:48 AM
crazytazo
Guest
 
Default Re: When parse result of lsof command, use awk

Dear Grant.
It works very well on my machine too.
thank you, that is the answer(and method) what I expect.

Reply With Quote
  #4  
Old 08-01-2008, 08:42 AM
Ed Morton
Guest
 
Default Re: When parse result of lsof command, use awk



On 8/1/2008 1:04 AM, Grant wrote:
> On Thu, 31 Jul 2008 22:28:11 -0700 (PDT), crazytazo <crazytazo@gmail.com> wrote:
>
>
>>lsof | awk '{ print $1 "\t" $7 "\t" $9 }'
>>
>>Through such commands
>>Select the field to make the output as shown below.
>>
>>[process, file size, filename]
>>ifdcd 3287239193 /home0031/ICFS/0000000000000000900/filename.sh
>>
>>
>>but if filename field includes whitespaces charactor, ex) "/home0031/
>>ICFS/0000000000000000900/filen ame.sh"
>>it will be shown below,
>>
>>ifdcd 3287239193 /home0031/ICFS/0000000000000000900/filen
>>
>>
>>How do you resolve them?

>
>
> How about:
>
> $ lsof | awk '{ printf $1 "\t" $7 "\t";for(i=9;i<=NF;i++)printf $i" ";print""}'


ITYM:

$ lsof |
awk '{ printf $1 "\t" $7 "\t";for(i=9;i<=NF;i++)printf "%s ",$i;print""}'

see below.

> ...
> lsof 736 /home/common
> lsof 432 /
> lsof 102528 /usr/bin/lsof
> lsof 0 (stat: No such file or directory)
> lsof 178476 /usr/lib/locale/en_US/LC_CTYPE
> lsof 1441201 /lib/tls/libc-2.3.6.so
> lsof 104536 /lib/ld-2.3.6.so
> lsof 149806
> lsof 149807
>
> This works here on linux 'cos $9 is last field
>
> Grant.


That'll only work if there's just a siangle blank char in the file name. If
there's 2 contiguous blanks, it'll mangle the file name. It'll also fail if the
file name contains any printf formating characters (e.g. "%s") since you're
using "$i" where the formating field should be. Use:

printf fmt,data
not:
printf data

How about this:

$ lsof | awk -v OFS='\t' '{file=$0;
sub(/^[[:space:]]*([^[:space:]]*[[:space:]]*){8}/,"",file); print $1,$7,file}'

It'll only work if your awk supports RE intervals (e.g a POSIX awk). To get that
in GNU awk, use:

$ lsof | gawk --re-interval -v OFS='\t' '{file=$0;
sub(/^[[:space:]]*([^[:space:]]*[[:space:]]*){8}/,"",file); print $1,$7,file}'

If you KNOW there's no leading white space and each field is separated by a
single blank, you can simplify a bit:

$ lsof | awk -v OFS='\t' '{file=$0; sub(/([^ ]* *){8}/,"",file); print $1,$7,file}'

Regards,

Ed.

Reply With Quote
  #5  
Old 08-01-2008, 02:40 PM
Grant
Guest
 
Default Re: When parse result of lsof command, use awk

On Fri, 01 Aug 2008 07:42:21 -0500, Ed Morton <morton@lsupcaemnt.com> wrote:

>
>
>On 8/1/2008 1:04 AM, Grant wrote:
>> On Thu, 31 Jul 2008 22:28:11 -0700 (PDT), crazytazo <crazytazo@gmail.com> wrote:
>>
>>
>>>lsof | awk '{ print $1 "\t" $7 "\t" $9 }'
>>>
>>>Through such commands
>>>Select the field to make the output as shown below.
>>>
>>>[process, file size, filename]
>>>ifdcd 3287239193 /home0031/ICFS/0000000000000000900/filename.sh
>>>
>>>
>>>but if filename field includes whitespaces charactor, ex) "/home0031/
>>>ICFS/0000000000000000900/filen ame.sh"
>>>it will be shown below,
>>>
>>>ifdcd 3287239193 /home0031/ICFS/0000000000000000900/filen
>>>
>>>
>>>How do you resolve them?

>>
>>
>> How about:
>>
>> $ lsof | awk '{ printf $1 "\t" $7 "\t";for(i=9;i<=NF;i++)printf $i" ";print""}'

>
>ITYM:
>
>$ lsof |
>awk '{ printf $1 "\t" $7 "\t";for(i=9;i<=NF;i++)printf "%s ",$i;print""}'


Okay.
>
>see below.
>
>> ...
>> lsof 736 /home/common
>> lsof 432 /
>> lsof 102528 /usr/bin/lsof
>> lsof 0 (stat: No such file or directory)
>> lsof 178476 /usr/lib/locale/en_US/LC_CTYPE
>> lsof 1441201 /lib/tls/libc-2.3.6.so
>> lsof 104536 /lib/ld-2.3.6.so
>> lsof 149806
>> lsof 149807
>>
>> This works here on linux 'cos $9 is last field
>>
>> Grant.

>
>That'll only work if there's just a siangle blank char in the file name. If
>there's 2 contiguous blanks, it'll mangle the file name. It'll also fail if the
>file name contains any printf formating characters (e.g. "%s") since you're
>using "$i" where the formating field should be. Use:
>
> printf fmt,data
>not:
> printf data


Yep, didn't think of that.
>
>How about this:
>
>$ lsof | awk -v OFS='\t' '{file=$0;
>sub(/^[[:space:]]*([^[:space:]]*[[:space:]]*){8}/,"",file); print $1,$7,file}'
>
>It'll only work if your awk supports RE intervals (e.g a POSIX awk). To get that
>in GNU awk, use:
>
>$ lsof | gawk --re-interval -v OFS='\t' '{file=$0;
>sub(/^[[:space:]]*([^[:space:]]*[[:space:]]*){8}/,"",file); print $1,$7,file}'
>
>If you KNOW there's no leading white space and each field is separated by a
>single blank, you can simplify a bit:
>
>$ lsof | awk -v OFS='\t' '{file=$0; sub(/([^ ]* *){8}/,"",file); print $1,$7,file}'


The OP's problem is worse because lsof sometimes skips (has empty) fields
so perhaps OP should be using the fixed field offset option because his $9
filename start may miss earlier bits of filename with standard whitespace
field splitting.

crazytazo, see:
http://www.gnu.org/software/gawk/man...#Constant-Size

Grant.
--
http://bugsplatter.id.au/
Reply With Quote
  #6  
Old 08-07-2008, 09:36 AM
Ed Morton
Guest
 
Default Re: When parse result of lsof command, use awk

On 8/6/2008 11:02 PM, John DuBois wrote:
> In article <43836fb3-767d-442b-85ff-eed846557443@i20g2000prf.googlegroups.com>,
> crazytazo <crazytazo@gmail.com> wrote:
>
>>lsof | awk '{ print $1 "\t" $7 "\t" $9 }'
>>
>>Through such commands
>>Select the field to make the output as shown below.
>>
>>[process, file size, filename]
>>ifdcd 3287239193 /home0031/ICFS/0000000000000000900/filename.sh
>>
>>
>>but if filename field includes whitespaces charactor, ex) "/home0031/
>>ICFS/0000000000000000900/filen ame.sh"
>>it will be shown below,
>>
>>ifdcd 3287239193 /home0031/ICFS/0000000000000000900/filen
>>
>>
>>How do you resolve them?
>>
>>I was try change field seperator to Tab charactor, but it was not
>>work.

>
>
> Use lsof's -F option. See the man page.
>
> A little library function I wrote some years ago that uses the -F option and
> parses the output is available at:
>
> ftp://ftp.armory.com/pub/lib/awk/dolsof


Just watch out for the getline in there as it will overwrite your current record
(if you call that function while processing a record), and it MAY not terminate
in error scenarios (although it should with gawk or a POSIX awk). This section
of the function:

while ((ret = (Cmd | getline)) == 1) {
field = substr($0,1,1)
value = substr($0,2)

should be written as:

while ((ret = (Cmd | getline cmdOut)) > 0) {
field = substr(cmdOut,1,1)
value = substr(cmdOut,2)

and cmdOut should be added to the list of local variables to avoid those
problems. See http://tinyurl.com/yn9ka9 for more getline usage info.

I'm actually not sure what the point of the "ret" variable is though as, unless
I'm misreading it, the only way to get out of that loop is if ret is zero so
there's no point saving and returning that, which is presumably why it isn't
used in the calling code below, so the above should really just be:

while ((Cmd | getline cmdOut) > 0) {
field = substr(cmdOut,1,1)
value = substr(cmdOut,2)

and "ret" should be removed from the rest of the function.

Ed.

>
> To get the output you want, you might do:
>
> BEGIN {
> dolsof("csn", "", out, pids)
> for (pid in pids)
> for (i = 1; i <= out[pid]; i++)
> printf "%s %d %s\n", out[pid,"c"], out[pid,"s",i], out[pid,"n",i]
> }
>
> John


Reply With Quote
Reply


Thread Tools
Display Modes


All times are GMT -5. The time now is 08:46 AM.


Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
vB Ad Management by =RedTyger=

In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.