## Saturday, May 24, 2008

### Check for presence in a line : Awk

Input File:

\$ cat atnd.txt
AA,BB,CC,DD,EE
BB,CC,EE
AA,BB,DD
AA,CC,DD,EE

Check whether AA,BB,CC,DD,EE records are present in each line.
If present, put a (P), if not put a (A)

i.e. Required Output:

AA(P) BB(P) CC(P) DD(P) EE(P)
AA(A) BB(P) CC(P) DD(A) EE(P)
AA(P) BB(P) CC(A) DD(P) EE(A)
AA(P) BB(A) CC(P) DD(P) EE(P)

Awk solution:
`\$ awk 'BEGIN{FS=",";OFS=" "n=split("AA,BB,CC,DD,EE",a,FS)}{for(i=1;i<=n;i++) { s=match(\$0,a[i])?a[i]"(P) ":a[i]"(A) " printf("%s",s)}print ""}' atnd.txt`

Unknown said...

Hey This works great!!!..can u tell me how to get the count instead of P?

Unknown said...

@Sanjanaa Nagarajan, thanks for the query. Could you please put the expected output for this example, I would try that. Thanks.

Unknown said...

For example:

AA,BB,CC,DD,EE,AA
BB,CC,EE,EE
AA,BB,DD,DD,DD
AA,CC,DD,EE

Required Output:

AA(2) BB(1) CC(1) DD(1) EE(1)
AA(A) BB(1) CC(1) DD(A) EE(2)
AA(1) BB(1) CC(A) DD(3) EE(A)
AA(1) BB(A) CC(1) DD(1) EE(1)

Unknown said...

sed -e '
1{
x
s/.*/AA(A) BB(A) CC(A) DD(A) EE(A)/
x
}

/\n/!G
s/,/\n/

/^\(.*\)\n.*\n\(.*[ ]\)\{0,1\}\1(A)/{
s//&\n/
s/(A)\n/(P)/
}
/\n.*\n/D
/^\(.*\)\n\(.*[ ]\)\{0,1\}\1(A)/{
s//&\n/
s/(A)\n/(P)/
}

s/.*\n//

x
s/.*/AA(A) BB(A) CC(A) DD(A) EE(A)/
x
' < atnd.txt

perl -lpe '
my \$l = \$_;
\$_ = join " ",
map { \$l =~ /(?:^|,)\$_(?:,|\$)/ ? "\$_(P)" : "\$_(A)" }
qw/AA BB CC DD EE/;
' < atnd.txt

For the case of showing the match with numbers as reqd by OP S. Nagarajan:

perl -ple '
my \$l = \$_;
\$_ = join \$", map {
my \$k =(()= \$l =~ /(?:(?<=^)|(?<=,))\$_(?=(?:,|\$))/g) || "A";
"\$_(\$k)";
} qw/AA BB CC DD EE/
' atnd.txt