67

I have:

1 LINUX param1 value1 
2 LINUXparam2 value2
3 SOLARIS param3 value3
4 SOLARIS param4 value4

I need awk to print all lines in which $2 is LINUX.

ivanleoncz
  • 9,070
  • 7
  • 57
  • 49
yael
  • 2,765
  • 10
  • 40
  • 48

6 Answers6

106

In awk:

awk '$2 == "LINUX" { print $0 }' test.txt

See awk by Example for a good intro to awk.

In sed:

sed -n -e '/^[0-9][0-9]* LINUX/p' test.txt

See sed by Example for a good intro to sed.

jsonfry
  • 2,067
  • 2
  • 15
  • 16
Hank Gay
  • 70,339
  • 36
  • 160
  • 222
  • what about LINUX can be linux or Linux ? – yael Jun 02 '10 at 11:52
  • The pages I linked to explain about how to use regexes in the respective tools. The regex to match LINUX or Linux is L(INUX|inux) (roughly speaking; different tools sometimes have slightly different syntax). BTW, if this is homework, it should be tagged as such. – Hank Gay Jun 02 '10 at 12:40
  • If you want the match to be completely case insensitive, check out the `toupper` (or `tolower`) functions in `awk`. – Hank Gay Jun 02 '10 at 14:39
  • 14
    Note that the default action already is `print $0`, so this is all that's required: `awk 'toupper($2)=="LINUX"' test.txt` – glenn jackman Jun 02 '10 at 19:10
  • 2
    @HankGay "awk by Example" URL is not valid anymore. – Arsen Khachaturyan May 08 '20 at 10:20
  • 1
    @ArsenKhachaturyan `Awk by example` now lives at https://developer.ibm.com/tutorials/l-awk1/ – Dale C. Anderson Mar 01 '21 at 19:36
25

This is a case in which you can use the beautiful idiomatic awk:

awk '$2=="LINUX"' file

That is:

  • The default action of awk when in a True condition is to print the current line.
  • Since $2 == "LINUX" is true whenever the 2nd field is LINUX, this will print those lines in which this happens.

In case you want to print all those lines matching LINUX no matter if it is upper or lowercase, use toupper() to capitalize them all:

awk 'toupper($2)=="LINUX"' file

Or IGNORECASE with either of these syntaxs:

awk 'BEGIN {IGNORECASE=1} $2=="LINUX"' file
awk -v IGNORECASE=1 '$2=="LINUX"' file
fedorqui
  • 275,237
  • 103
  • 548
  • 598
15

My answer is very late, but no one has mentioned:

awk '$2~/LINUX/' file
enegue
  • 261
  • 2
  • 5
  • 1
    I like this one, because is matches partial strings, ie it would still match LINUX_OS for example – mosh Mar 31 '20 at 22:36
  • sorry for necroing but far more versatile solution than others – Fedja M. Dec 28 '21 at 09:32
  • If you need a regular expression - yes, upvoted for this. But if you need exact match, others make more sense. – akostadinov Feb 28 '23 at 19:02
  • @akostadinov: For an exact match use: *awk '$2~/^LINUX$/' file* – enegue Mar 02 '23 at 01:46
  • 1
    @enegue, why should I use a regex for an exact match? Moreover if I want to match special characters the regex will go even more in the way. Don't try to use a hammer instead of a screwdriver or vise versa. – akostadinov Mar 02 '23 at 13:57
  • Regex is just an alternative tool, that is, in the case of the OP, quite simple to implement -- as you can see. BTW, thank you for your upvote. – enegue Mar 04 '23 at 00:22
6

Try these out:

egrep -i '^\w+ LINUX ' myfile

awk '{IGNORECASE=1}{if ($2 == "LINUX") print}' myfile

sed -ne '/^[0-9]* [Ll][Ii][Nn][Uu][Xx] /p' myfile

edit: modified for case insensitivity

B Johnson
  • 2,408
  • 3
  • 20
  • 32
5

I think it might be a good idea to include "exact" and "partial matching" cases using awk ))

So, for exact matching:

OTHER_SHELL_COMMAND | awk '$2 == "LINUX" { print $0 }'

And for partial matching:

OTHER_SHELL_COMMAND | awk '$2 ~ /LINUX/ { print $0 }'
Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42
4

In GNU sed case-insensitive matches can be made using the I modifier:

sed -n '/^[^[:space:]][[:space:]]\+linux[[:space:]]\+/Ip'

Will robustly match "linux", "Linux", "LINUX", "LiNuX" and others as the second field (after the first field which may be any non-whitespace character) and surrounded by any amount (at least one) of any whitespace (primarily space and tab, although you can use [:blank:] to limit it to strictly those).

Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439