advanced awk

Hi all

Input

group1	user1
	user2
	user3
group2	user4
	user5
	user1
group3	user6
	user7
	user8

Desired output

group1
group2

So far I've tried, but did not work

BEGIN
{
  i=0;                                  # declaring variable
}

{
  if (NF==2){currgrp=$1;}               # check whether awk actually processing 2 column record, if yes save the group name
  else
     {
      if ($1~/uname/)                   # else if awk is processing 1 column record and is found user name, save the group name to array and increment i
       {
         netgroups=currgrp;
         i++;
       }
     }
}

END                                     # at the end of processing whole file print the array (all saved groups)
{
  for(j=0;j<i;j++)
  {
    print netgroups;
  }
}

skript was called

awk -v uname="user1" -f awkscript.awk group_file

what is wrong with script above ?

It was a bit complicated, I think for the task?

$ cat Test1
awk '
 $2 { G = $1 }
 $NF == U && ! _[G]++ { print G }
' U="$1" file1

$ cat file1
group1	user1
	user2
	user3
group2	user4
	user5
	user1
group3	user6
	user7
	user8

$ ./Test1 user1
group1
group2

This one should work:

awk -v uname="user1" 'END {
  while (++j <= i) print netgroups[j]
  }
NF == 2 { currgrp = $1 }
$0 ~ uname { netgroups[++i] = currgrp }
' group_file

Use gawk, nawk or /usr/xpg4/bin/awk on Solaris.

---------- Post updated at 07:47 PM ---------- Previous update was at 07:39 PM ----------

Sure, no END block is needed :slight_smile:

awk  'NF == 2 { g = $1 }
$NF ~ u && $0 = g x
' u="user1" group_file

One of the previous solutions will fail if the username is 0 :slight_smile:

... and my code assumes unique group names.

Thank you guys,
To radulov: your solution is so similar to mine, don't you know why mine is not working ? Seems more similar to me :wink:

$ u=user1
$ sed -n '/^group/h; /'"$u"'/{g;s/[[:blank:]].*$//;p;}' file
group1
group2

I would recommend against using this type of solution unless you can guarantee that the user name will not contain any sed regular expression special characters ("/", ".", "*", "\" .. come immediately to mind).

You have been warned :wink:

Alister

Comments inline.

BEGIN {                          # do not put BEGIN on a line by itself   
  i = 0                          # no need to initialize the counter,
                                 # awk does this automatically
  }                                 
{
  if (NF == 2) {
    currgrp = $1
    if ($2 ~ uname) {
      netgroups = currgrp     # you shoud check if the username matches 
      i ++                       # when NF == 2 too
      }
    }        
  else
     {
      if ($1 ~ uname) {           # /uname/ matches litteral "uname"
         netgroups = currgrp
         i ++
       }
     }
}

END {                             # do not put END on a line by itself
  for(j = 0; j < i;j ++)             
  {
    print netgroups[j]            # j not i!
  }
}

There's nothing wrong with those two lines. BEGIN and END are syntactically no different from any other pattern. So long as the corresponding action begins on the same line (the opening curly brace is sufficient), it's fine.

Example:

$ cat beginend.awk 
BEGIN {
    print "begin"
}

END {
    print "end"
}

$ echo | awk -f beginend.awk 
begin
end

Regards,
Alister

Exactly!
I posted a working code ...
See the OP's code :slight_smile:

My apologies, radoulov. I misunderstood what was going on (that's twice in this thread, the first was edited away ;)).

Cheers,
Alister

Another variation:

awk 'NF-1{g=$1} $NF==u{print g}' u=user1 infile

No problem :slight_smile:

---------- Post updated at 10:04 PM ---------- Previous update was at 10:01 PM ----------

Good point,
I suppose the OP meant == not ~ .

---------- Post updated at 10:21 PM ---------- Previous update was at 10:04 PM ----------

Just to add that the special patterns BEGIN and END are actually syntactically different from the regular patterns because they require an action part.

Thank you guys, you helped a lot :b:

nawk -v U="user1" 'NF>1{cgrp[x=$1]++ }($NF==U)&&cgrp[x]{print x}'