How to print columns if only a specific values is matched in a Linux?

Viewed 779

I have a sample.txt file like this:

abc shk ansjc
def xyz dkksk
ghd ssk jshhd
djsh xyz dsoop
ssd swl jsjdl 

I want to print column1 & column2 but column2 can be printed if only the content is matching with "xyz", so the output will be as follows.

abc
def xyz
ghd 
djsh xyz
ssd

This is what I tried so far,

awk '$2 == "xyz" { print $1,$2 }' output2.txt || awk '$2 != "xyz" { print $1 }'

Can anyone help me to get this output?

6 Answers

Here is another POSIX complaint awk solution:

awk '{print $1 ($2 == "xyz" ? OFS $2 : "")}' file

abc
def xyz
ghd
djsh xyz
ssd

With your shown samples, you could try following.

awk '{printf("%s%s",$1,($2=="xyz"? OFS $2:"")ORS)}' Input_file

OR

awk '{printf("%s%s\n",$1,($2=="xyz"? OFS $2:""))}' Input_file

Explanation: Simple explanation would be, using printf function of awk to print the values in current line(as per OP's need). In it firstly printing 1st field, then while printing 2nd value, checking condition if 2nd field is xyz then print space with $2 followed by new line else only print new line.

With an awk implementation that allows manipulation of NF (ex: GNU awk and mawk):

$ awk '{NF = $2=="xyz" ? 2 : 1} 1' ip.txt
abc
def xyz
ghd
djsh xyz
ssd

You can also use awk 'NF = $2=="xyz" ? 2 : 1' since the expression will evaluate to true.

I suggest with awk:

awk '$2=="xyz"{print $1,$2; next} {print $1}' sample.txt

or

awk '{ if($2=="xyz"){print $1,$2} else {print $1} }' sample.txt

Output:

abc
def xyz
ghd
djsh xyz
ssd

With sed:

sed -E 's/^([^ ]+ xyz).*/\1/; t; s/ .*//'

Or more portably:

sed -E -e 's/^([^ ]+ xyz).*/\1/' -e 't' -e 's/ .*//'

An alternative using grep with an optional group:

grep -o '^\S\+\( xyz\)\?\b' file

Or extended regexp

grep -oE '^\S+( xyz\b)?' file
  • ^ Start of string
  • \S+ Match 1+ non whitspace chars
  • ( xyz\b)? Optionally match a single space and xyz followed by a word boundary \b

Output

abc
def xyz
ghd
djsh xyz
ssd
Related