newbie
newbie

Reputation: 105

Total count filtered by parameters - bash

Is there a way to get the total number of lines that filters by certain parameters? For example, I have a log file that contains:

COMPLETED: location: DEN brand: A
COMPLETED: location: LHR brand: A
COMPLETED: location: EWR brand: C

COMPLETED: location: DEN brand: A
COMPLETED: location: LHR brand: B
COMPLETED: location: JFK brand: C

Is there a way to write the grep command that can return the total number of lines for each location and brand. For example, the command executed would return

DEN    A     3
LHR    A     1
LHR    B     1

This would have to be dynamic since the locations can be different. So we can't just do something like grep 'location: DEN' | grep 'brand: A' | wc -l >> file.log

Any suggestions would be helpful. Thanks.

Upvotes: 2

Views: 63

Answers (2)

RavinderSingh13
RavinderSingh13

Reputation: 133538

1st solution: With GNU awk please try following, written and tested with shown samples. Simple explanation would be, setting RS(record separator) to match DEN brand: A kind of values in each line. Then using split function to split RS values into arr1 array then creating final array which has values in it to be printed as per shown samples.

awk -v RS='[a-zA-Z]+[[:space:]]+brand:[[:space:]]+[a-zA-Z]+' '
RT{
  split(RT,arr1," brand: ")
  arr[arr1[1] OFS arr1[2]]++
}
END{
  for(key in arr){
    print key,arr[key]
  }
}
' Input_file

2nd solution: Using match function of awk here. Simple explanation would be using match to match DEN brand: A values in line here, then splitting matched values into arr. Finally cnt array which has index as 1st and 2nd value of arr. in END block of awk program printing all values of array ant there.

awk '
match($0,/[a-zA-Z]+ brand: [a-zA-Z]+/){
  split(substr($0,RSTART,RLENGTH),arr," brand: ")
  cnt[arr[1] OFS arr[2]]++
}
END{
  for(key in cnt){
    print key,cnt[key]
  }
}
'  Input_file

Upvotes: 0

Mikołaj Głodziak
Mikołaj Głodziak

Reputation: 5277

You can do this also with Bash commands:

cat input_file | sed '/^$/d' | sort | uniq -c | sed 's/^ \+//' | cut -d' ' -f1,4,6

in this situation output will be as follow:

2 DEN A
1 EWR C
1 JFK C
1 LHR A
1 LHR B

Upvotes: 2

Related Questions