-1

I have a datafile as below.

datafile

Sterling|Man City|England
Kane|Tottenham|England
Ronaldo|Man Utd|Portugal
Ederson|Man City|Brazil

If I want to find a player that has a "Man City" and "England" trait I would write a command as such in the interpreter.

grep "Man City" datafile | grep "England"
output: Sterling|Man City|England

Like this, I want to make a shell script that receives multiple(more than 1) arguments that finds a line which has all the arguments in it. It would receive input as arg1 arg2 arg3... and return all the data lines that has the arguments. The program would run like this.

$ ./find ManCity England 
output: Sterling|Man City|England

But I have absolutely no idea how to implement the command that does multiple grep for each argument. Can you use a for loop and implement in a code that does something like this?

grep arg1 datafile | grep arg2 | grep arg3 ... 

Also, if there is a better way to find a data line that has all the arguments(AND of the arguments) can you please show me how?

Hanrabong
  • 35
  • 4

2 Answers2

0

You can use the awk command to do so. Awk is a very useful command and also supports loops.

Below is the awk command to find the AND of multiple patterns:

> awk '/Man City/ && /England/' test.txt

Sterling|Man City|England

Incase you want to do OR:

> awk '/Man City/ || /England/' test.txt
Sterling|Man City|England
Kane|Tottenham|England
Ederson|Man City|Brazil

Reference

aru_sha4
  • 368
  • 2
  • 11
  • Thanks for your answer! But is there a way to implement the AND operation directly in the shell code without touching awk? Is it possible to implement my idea of using for loops in each grep? – Hanrabong Mar 19 '22 at 11:30
0

You need this:

#!/bin/bash
myArray=( "$@" ) # store all parameters as an array
grep="grep ${myArray[0]} somefile" # use the first param as the first grep
unset myArray[0]; # then unset the first param
for arg in "${myArray[@]}"; do 
   grep="$grep | grep '$arg'" # cycle through the rest of the params to build the AND grep logic
done
eval "$grep" # and finally execute the built line
Ron
  • 5,900
  • 2
  • 20
  • 30