showkey
showkey

Reputation: 236

how to use awk command to cut field?

there is a file ,which you can get by command ps aux in linux.

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   2280   732 ?        Ss   08:20   0:00 init [2]  
root       327  0.0  0.1   2916  1456 ?        Ss   08:20   0:00 udevd --daemon
root      1681  0.0  0.0   2376   800 ?        Ss   08:20   0:00 /sbin/rpcbind -w
root      2071  0.0  0.1  27920  1708 ?        Sl   08:20   0:00 /usr/sbin/rsyslogd -c5

i want to get the content of last field,such as:

COMMAND
init [2]
udevd --daemon
/sbin/rpcbind -w
/usr/sbin/rsyslogd -c5

when i use , $ awk '{print $11}' test,i get:

COMMAND
init
udevd
/sbin/rpcbind
/usr/sbin/rsyslogd

when i use ,$ awk '{print $12}' test,i get :

[2]
--daemon
-w
-c5

how can i do?

Upvotes: 3

Views: 24484

Answers (8)

ufopilot
ufopilot

Reputation: 3985

$ rev file | awk 'NF-=10' | rev
$ ps aux | rev | awk 'NF-=10' | rev
COMMAND
init [2]
udevd --daemon
/sbin/rpcbind -w
/usr/sbin/rsyslogd -c5

Upvotes: 0

RARE Kpop Manifesto
RARE Kpop Manifesto

Reputation: 2925

echo '
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   2280   732 ?        Ss   08:20   0:00 init [2]     
root       327  0.0  0.1   2916  1456 ?        Ss   08:20   0:00 udevd --daemon 
root      1681  0.0  0.0   2376   800 ?        Ss   08:20   0:00 /sbin/rpcbind -w 
root      2071  0.0  0.1  27920  1708 ?        Sl   08:20   0:00 /usr/sbin/rsyslogd -c5' | 

# emulate [ cut ] and hardcode in the chopping width via [ FS ]:

mawk NF++ OFS= FS='.{65}'
gawk '$0 = $2' FS='.{65}'

# emulate [ cut ] and hardcode in the chopping width, but via [ RS ] instead:

nawk NF RS='(^|\n)(.{65}|$)'

# using a byte sentinel ( 0x1 ) that shouldn't show up normally

mawk 'sub(_,"\1",$11) + sub(/.+\1/,_)' 
nawk 'sub(/.+\1/,_, $!sub(_,"\1",$11))'

# pure regex without hard-coding in widths or column counts, 
# and very sure ":" doesn't show up in right most column

gawk NF=NF FS='^(.+[ \t][0-9]:[0-9][0-9]|USER[ \t].+[ \t]TIME)[ \t]' OFS=

COMMAND
init [2]
udevd --daemon
/sbin/rpcbind -w
/usr/sbin/rsyslogd -c5

** In the sentinel variants, the single underscore variable (_) serves 2 different regex roles

  • the former being a shorthand for sub(//,...), which is same as sub(/^/,...)
  • the latter as the empty replacement string ("")

Upvotes: 0

kenorb
kenorb

Reputation: 166929

Try:

ps aux | awk '{$1=""; $2=""; $3=""; $4=""; $5=""; $6=""; $7=""; $8=""; $9=""; $10=""; gsub(/^ +/, "", $0); print}'

Related: awk / cut: Skip First Two Fields and Print the Rest of Line.

Upvotes: 0

adkisson
adkisson

Reputation: 465

The existing answer didn't work on awk version 20070501, it printed leading spaces. This worked.

awk '{for(i=1;i<11;i++)$i="";$0=$0;$1=$1;print}'

Upvotes: 0

Dilip Muthukurussimana
Dilip Muthukurussimana

Reputation: 719

For the above output, this should work:

ps aux | cut -c66-

NOTE: Watch out the last '-'. If you miss it, you will get only the 66th char!!!

However for this to work every time, the COMMAND column should start at 66th char position. If it is different, note the COMMAND column's number and change the cut command like this

cut -c<column#>-

Upvotes: 1

user1461760
user1461760

Reputation:

You can loop over the words of the last field and print them:

ps aux | awk '{ for( i=11 ; i <=NF ; i++ ) { printf( "%s ", $i ) } ; print "" }'

If you want to process the command afterwards, you can put it in a variable:

ps aux | awk '{ CMD = "" ; for( i=11 ; i <=NF ; i++ ) { CMD = CMD " " $i } ; sub( /^ /, "", CMD ) ; print CMD }'

Upvotes: 2

radical7
radical7

Reputation: 9144

If you're not required to use awk, the following also works:

ps aux | tr -s ' ' ' ' | cut -d' ' -f11-

Deciphering that a bit. Since ps separates its columns with spaces,

tr -s ' ' ' '

replaces repeated strings of spaces (as specified by the first string [the first set of ' ']) with a single space (specified in the second string). Now, since the fields are now single space separated, we can use

cut -d' ' -f11-

which says that fields are separated by a space (the character after the '-d'), and to select fields 11 to the end of the line (denoted as the '-f11-').

This might seem a little more complicated at first look, but it really simplifies parsing separated-value strings once you get the hang of it.

Upvotes: 1

Vijay
Vijay

Reputation: 67319

awk '{for(i=1;i<11;i++)$i="";print }'

or you can just do:

awk '{print $11,$12}'

Upvotes: 6

Related Questions