1

I want to subset data with awk. Let's say I have this file called test:

IP MAC Bandwidth etc etc

192.1.1.1 ff:ff:ff:ff 5.421M
192.1.2.3 ff:ff:ff:f3 5.120M
192.1.2.5 ff:ff:ff:f1 5.100M

stuff I don't want to be selected

I want to select just the bandwith values (much better if I can delete the M and the end, maybe with sed, I am not sure how, but that is not the main problem.)

The best subset I am doing for the moment is with:

awk '{print $3}' test

And the output is this:

Bandwidth

5.421M
5.120M
5.100M

dont

But I want it to be:

5.421
5.120
5.100

If the "M" is there it's not a problem but that is the idea. I have been collecting information about awk and trying stuff but haven't gotten to the solution.

1
  • Whats the 'stuff' you don't want selected ?
    – user78605
    Oct 30 '14 at 8:38
3

The exact answer requires that you specify your problem a bit more. However, the general syntax of an awk statement is:

PATTERN { ACTION }

ACTION will only be executed for lines that match PATTERN. Thus, we can use PATTERN to subset by row, and the ACTION block to subset by column. For instance, given your input, I might use the following:

> awk '/^[0-9]/ {print $3 }' INPUTFILE
5.421M
5.120M
5.100M

the PATTERN here is a regular expression that matches any line where the first character is an integer from 0 to 9. To remove the M you could either pipe this to another command such as tr or use the gsub command as in cuonglm's answer

awk '/^[0-9]/ { gsub(/M/, "", $3); print $3 }' INPUT_FILE
1
  • You can also use +<FIELD> to remove characters after a number such as awk '/^[0-9]/{print +$3}' although this will remove unnecessary 0s. To keep formatting use awk '/^[0-9]/ {printf("%.3f\n",+$3)}'
    – user78605
    Oct 30 '14 at 11:27
1

You can remove all thing that are not digit or dot before printing:

$ awk '{gsub(/[^[:digit:].]/,"",$3);print $3}' file
5.421
5.120
5.100
1
  • I dont why that gives me the same output as awk '{print $3}' test
    – aDoN
    Oct 30 '14 at 9:11
1

If you don't intend to make some operation with text the sed usage seems is more resonable

sed -En 's/.* (\S+)M$/\1/p'

-E let's to avoid meta-characters usage with backslash (\(, \+, etc.)

-n suppress output exept ordered by p

s/ substitute

.* first part of the line for space (the last space becouse greedy)

() "revers link" - you can call pattern inside brackets by \number

\S every non-space simbol (everything exept :blank:)

+ one or more previous simbol

M$ "M" at the end of line

/p print line where substitution is made

Meaning is "Substitute whole line by pattern inside brackets and print lines where such substitution is made only"

0
0

I haven't found a solution with awk but this worked:

cat test |grep ":"| cut -f3 -d " " | sed 's/[MGB]//g'
0

You can use match function in awk as well.

awk '{match($3, /[0-9]+.[0-9]+/,arr)}{ print arr[0]}' file
1
  • Please say gawk if using gawk-features.
    – user62916
    Oct 30 '14 at 11:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.