简体   繁体   中英

awk multiple strings in multiple fields

I have a file

file.txt

0005663;2018-04-24 10:14:58;Apple;2018-04-24 10:34:10;Banana;2018-04-24 15:03:16;Grape;2018-04-24 17:13:17;Grape
0005664;2018-04-24 10:14:58;Apple;2018-04-24 10:34:10;Avocado;2018-04-24 15:03:16;Orange;2018-04-24 17:13:17;Orange
0005665;2018-04-24 10:14:58;Apple;2018-04-24 10:34:10;Cherry;2018-04-24 15:03:16;Lemon;2018-04-24 15:14:10;Apple;2018-04-24 15:41:10;Orange;2018-04-24 17:13:17;Orange
0005666;2018-04-24 10:14:58;Apple;2018-04-24 10:34:10;Banana;2018-04-24 15:03:16;Melon;2018-04-24 16:13:11;Grape;2018-04-24 17:13:17;Grape
0005667;2018-04-24 10:14:58;Apple;2018-04-24 10:34:10;Melon;2018-04-24 15:03:16;Grape;2018-04-24 17:13:17;Grape
0005668;2018-04-24 10:14:58;Apple;2018-04-24 10:34:10;Cherry;2018-04-24 15:03:16;Grape;2018-04-24 16:13:11;Grape;2018-04-24 17:13:17;Papaya

My log has several fields, depending on which path the client made. It can have 7, or 8, 9 fields, as can be 14 or 16 ... I need to get the lines that had this route:

  • in the third field = Apple
  • in the fifth field = Banana, Avocado or Cherry
  • and the seventh field ahead = Apple, Grape, Orange or Lemon and not be Melon or Papaya

To make this route to the seventh field I do so

awk -F";" '($3~/Apple/) && ($5~/Banana/ || $5~/Avocado/ || $5~/Cherry/) && ($7~/Apple/ || $7~/Grape/ || $7~/Orange/ || $7~/Lemon/) &&! ($7~/Melon/ || $7~/Papaya/)' file.txt

how to do with ninth field or eleventh ... without having to write a rule for each lenght?

the output would look like this:

0005663;2018-04-24 10:14:58;Apple;2018-04-24 10:34:10;Banana;2018-04-24 15:03:16;Grape;2018-04-24 17:13:17;Grape
0005664;2018-04-24 10:14:58;Apple;2018-04-24 10:34:10;Avocado;2018-04-24 15:03:16;Orange;2018-04-24 17:13:17;Orange
0005665;2018-04-24 10:14:58;Apple;2018-04-24 10:34:10;Cherry;2018-04-24 15:03:16;Lemon;2018-04-24 15:14:10;Apple;2018-04-24 15:41:10;Orange;2018-04-24 17:13:17;Orange

Could you please try following and let me know if this helps you.

awk -F";" '
($3=="Apple" && ($5=="Banana" || $5=="Avocado" || $5=="Cherry")){
  for(i=6;i<=NF;i++){
    if($i ~ /Apple|Grape|Orange|Lemon/){  flag=1    }
    if($i ~ /Melon|Papaya/)            {  non_flag=1}
  }
  if(!non_flag && flag)                {  print     }
  non_flag=flag=""
}'  Input_file

If I am reading it right OP is saying greater than field 5 Papaya and Melon shouldn't come

and in fields greater than 5 = Apple, Grape, Orange or Lemon and not be Melon or Papaya

So keeping that in mind have written this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM