How to exclude certain combination pattern in data set in Webfocus? - webfocus

enter code hereI have a data set where I have to get rid off the student if he/she has the grade other than "F". here in an example, Brian has grades other than "F", so, Brian should not appear in my result. Only Jack should appear, as, I want EXCLUSIVELY "F" grade students.
Webfocus data
I tried it in Webfocus using OMITS, NE functions, but I am not able to resolve the issue (Please click to see the screen shot).
As mentioned above, I am only expecting jack's record, as Brian has grades other than "F". I would really appreciate your help. Thanks.
I am stuck at the last line in a code:
TABLE FILE TABLE1
PRINT
ID
NAME
Grade
WHERE (ID OMITS (PRINT * from TABLE1 WHERE (Grade NE 'F')));

That's a very complex way of querying to WF!
This piece of code, its for loading the data you showed in the image:
-*
-* FILE ALLOCATION
-*
FILEDEF AMDEXAM DISK amdexam.ftm (APPEND
-RUN
-*
-* MASTER TO READ AMDS EXAMPLE
-*
EX -LINES 5 EDAPUT MASTER,AMDEXAM,CV,FILE
FILENAME=AMDEXAM, SUFFIX=FIX, SEGNAME=AMDEXAM, SEGTYPE=S0, $
FIELD=ID ,ALIAS=ID ,USAGE=A5 ,ACTUAL=A5 ,$
FIELD=NAME ,ALIAS=NAME ,USAGE=A10 ,ACTUAL=A10 ,$
FIELD=GRADE ,ALIAS=GRADE ,USAGE=A1 ,ACTUAL=A1 ,$
-*
-* LOAD FILE WITH SOME RECORDS
-*
-WRITE AMDEXAM A1 Brian A
-WRITE AMDEXAM A1 Brian B
-WRITE AMDEXAM A1 Brian B
-WRITE AMDEXAM A1 Brian A
-WRITE AMDEXAM A1 Brian C
-WRITE AMDEXAM A1 Brian F
-WRITE AMDEXAM A1 Brian F
-WRITE AMDEXAM A2 Jack F
-WRITE AMDEXAM A2 Jack F
-WRITE AMDEXAM A2 Mystic B
-WRITE AMDEXAM A3 Mystic A
-WRITE AMDEXAM A3 Mystic C
-WRITE AMDEXAM A3 Mystic C
-WRITE AMDEXAM A4 Joe F
-WRITE AMDEXAM A4 Joe F
-WRITE AMDEXAM A4 Ruben B
-WRITE AMDEXAM A4 Ruben A
-*
You could try something like this to achieve what you've asked:
TABLE FILE AMDEXAM
SUM
COMPUTE AA/I1 = IF ((LAST NAME NE NAME AND GRADE NE 'F') OR (LAST NAME EQ NAME AND LAST AA EQ 1)) THEN 1 ELSE 0; NOPRINT
BY ID
BY NAME
BY GRADE
WHERE TOTAL AA EQ 0
ON TABLE SET BYDISPLAY ON
END
-RUN
-EXIT
That should give you the grades of Bryan.
EDIT: Changed verb from PRINT to SUM to get only one record and NOPRINT to field AA.

Related

uniq -c in one column

Imagine we have a txt file like the next one:
Input:
a1 D1
b1 D1
c1 D1
a1 D2
a1 D3
c1 D3
I want to count the time each element in the first column appears but also keep the information provided by the second column (someway). Potential possible output formats are represented, but any coherent alternative is also accepted:
Possible output 1:
3 a1 D1,D2,D3
1 b1 D1
2 c1 D1,D3
Possible output 2:
3 a1 D1
1 b1 D1
2 c1 D1
3 a1 D2
3 a1 D3
1 c1 D3
How can I do this? I guess a combination sort -k 1 input | uniq -c <keep col2> or perhaps using awk but I was not able to write anything that works. However, all answers are considered.
I would harness GNU AWK for this task following way, let file.txt content be
a1 D1
b1 D1
c1 D1
a1 D2
a1 D3
c1 D3
then
awk 'FNR==NR{arr[$1]+=1;next}{print arr[$1],$0}' file.txt file.txt
gives output
3 a1 D1
1 b1 D1
2 c1 D1
3 a1 D2
3 a1 D3
2 c1 D3
Explanation: 2-pass solution (observe that file.txt is repeated), first pass does count number of occurences of first column value storing that data into array arr, second pass is for printing computed number from array, followed by whole line.
(tested in GNU Awk 5.0.1)
Using any awk:
$ awk '
{
vals[$1] = ($1 in vals ? vals[$1] "," : "") $2
cnts[$1]++
}
END {
for (key in vals) {
print cnts[key], key, vals[key]
}
}
' file
3 a1 D1,D2,D3
1 b1 D1
2 c1 D1,D3

Using bash to get Two variables in for-loop form two different lists

I'm working with bash and I have two lists:
AZU SJI IOP
A1 B1 C1
Using the bash code below:
for f1 in AZU SJI IOP
do
for f2 in A1 B1 C1
do
echo $f1 + $f2
done
done
I get this result:
$ bash dir.sh
AZU + A1
AZU + B1
AZU + C1
SJI + A1
SJI + B1
SJI + C1
IOP + A1
IOP + B1
IOP + C1
I would like to get the result in this way
AZU A1
SJI B1
IOP C1
Define two arrays such that they have the same indices, then iterate over the indices of one array:
list1=(AZU SJI IOP)
list2=(A1 B1 C1)
for i in "${!list1[#]}"; do
echo "${list1[i]} ${list2[i]}"
done
You could of course use paste, but since your lists are not in files, you might be interested in a solution without external commands:
set -- A1 B1 C1
for f1 in AZU SJI IOP
do echo $f1 $1
shift
done

Only display the largest number in head

I use sort -r | head and get the out put like this:
8 a1
8 a2
5 a3
5 a4
4 a5
4 a6
4 a7
4 a8
4 a9
4 a0
What can I do to make the output like this:
8 a1
8 a2
only the largest k1 number show up????
There are several ways to do it, but here is one using awk. Since it is already sorted, you want to check to just print lines that match the first value by piping the headed list into something like
awk 'BEGIN{maxval=0}; (maxval==0) {maxval=$1}; ($1==maxval) {print $0}'

Change the starter for loop index

I want to compare two lists without recombination in shell script:
A=(a b c d e)
B=(b c d e f)
then print a combination
ab
ac
ad
ae
af
bc
bd
be
bf
...
de
df
ef
I am tried with 'for ' loop
------------------------CODE----------------------------------------
arr_a=(a b c d e f)
for i in 0 1 2 3 4
do
jdx=$(( $i + 1 ))
for j in {$jdx..5}
do
echo ${arr_a[$i]}'_'${arr_a[$j]}
done
done
--------------------END CODE ------------------------------------
But the problem is $jdx.
Any hints to solve this issue?
You can use brace expansion to do this:
$ A=(a b c d e)
$ B=(b c d e f)
$ eval echo $(echo {${A[#]}}{${B[#]}} | tr ' ' ',')
ab ac ad ae af bb bc bd be bf cb cc cd ce cf db dc dd de df eb ec ed ee ef
This is first outputting the arrays in the form {a,b,c,d,e}{b,c,d,e,f}, then brace expansion takes care of the rest.
Use C-style for loops:
for ((i=0; i < ${#A[#]}; i++)); do
for ((j=i; j < ${#B[#]}; j++)); do
echo ${A[i]}${B[j]}
done
echo
done
ab
ac
ad
ae
af
bc
bd
be
bf
cd
ce
cf
de
df
ef

How to replace pairs of strings in two files to identical IDs?

[Update2] As it often happens, the scope of the task expanded quite a bit as a understood it better. The obsolete parts are crossed out, and you find the updated explanation below. [/Update2]
I have a pair of rather large log files with very similar content, except that some strings are different between the two. A couple of examples:
UnifiedClassLoader3#19518cc | UnifiedClassLoader3#d0357a
JBossRMIClassLoader#13c2d7f | JBossRMIClassLoader#191777e
That is, wherever the first file contains UnifiedClassLoader3#19518cc, the second contains UnifiedClassLoader3#d0357a, and so on. [Update] There are about 40 distinct pairs of such identifiers.[/Update]
UnifiedClassLoader3#19518cc | UnifiedClassLoader3#d0357a
JBossRMIClassLoader#13c2d7f | JBossRMIClassLoader#191777e
Logi18n#177060f | Logi18n#12ef4c6
LogFactory$1#15e3dc4 | LogFactory$1#2942da
That is, wherever the first file contains UnifiedClassLoader3#19518cc, the second contains UnifiedClassLoader3#d0357a, and so on. Note that all these strings are inside long lines of text, and they appear in many rows, intermixed with each other. There are about 4000 distinct pairs of such identifiers, and the size of each file is about 34 MB. So performance became an issue as well.
I want to replace these with identical IDs so that I can spot the really important differences between the two files. I.e. I want to replace all occurrences of both UnifiedClassLoader3#19518cc in file1 and UnifiedClassLoader3#d0357a in file2 with UnifiedClassLoader3#1; all occurrences of both Logi18n#177060f in file1 and Logi18n#12ef4c6 in file2 with Logi18n#2 etc. The counters 1 and 2 are arbitrary choices - the only requirement is that there is a one to one mapping between the old and new strings (i.e. the same string is always replaced by the same value and no different strings are replaced by the same value).
Using the Cygwin shell, so far I managed to list all different identifiers occurring in one of the files with
grep -o -e 'ClassLoader[0-9]*#[0-9a-f][0-9a-f]*' file1.log | sort | uniq
grep -o -e '[A-Z][A-Za-z0-9]*\(\$[0-9][0-9]*\)*#[0-9a-f][0-9a-f]*' file1.log
| sort | uniq
However, now the original order is lost, so I don't know which is the pair of which ID in the other file. With grep -n I can get the line number, so the sort would preserve the order of appearance, but then I can't weed out the duplicate occurrences. Unfortunately grep can not print only the first match of a pattern.
I figured I could save the list of identifiers produced by the above command into a file, then iterate over the patterns in the file with grep -n | head -n 1, concatenate the results and sort them again. The result would be something like
2 ClassLoader3#19518cc
137 ClassLoader#13c2d7f
563 ClassLoader3#1267649
...
Then I could (using sed itself) massage this into a sed command like
sed -e 's/ClassLoader3#19518cc/ClassLoader3#2/g'
-e 's/ClassLoader#13c2d7f/ClassLoader#137/g'
-e 's/ClassLoader3#1267649/ClassLoader3#563/g'
file1.log > file1_processed.log
and similarly for file2.
However, before I start, I would like to verify that my plan is the simplest possible working solution to this.
Is there any flaw in this approach? Is there a simpler way?
I think this does the trick, or at least comes close
#!/bin/sh
for PREFIX in file1 file2
do
cp ${PREFIX}.log /tmp/filter.$$.txt
FILE_MAP=`egrep -o -e 'ClassLoader[0-9a-f]*#[0-9a-f]+' ${PREFIX}.log | uniq | egrep -n .`
for MAP in `echo $FILE_MAP`
do
NUMBER=`echo $MAP | cut -d : -f 1`
WORD=`echo $MAP | cut -d : -f 2`
sed -e s/$WORD/ClassLoader#$NUMBER/g /tmp/filter.$$.txt > ${PREFIX}_processed.log
cp ${PREFIX}_processed.log /tmp/filter.$$.txt
done
rm /tmp/filter.$$.txt
done
Let me know if you have questions on how it works and why.
Here's my test data and the output
file1.log:
A1
UnifiedClassLoader3#a45bc1
A2
UnifiedClassLoader3#a45bc1
A3
UnifiedClassLoader3#a45bc1
A4
JBossRMIClassLoader#bc450a
A5
JBossRMIClassLoader#bc450a
A6
JBossRMIClassLoader#bc450a
B1
UnifiedClassLoader3#a45bc2
B2
UnifiedClassLoader3#a45bc2
B3
UnifiedClassLoader3#a45bc2
B4
JBossRMIClassLoader#bc450b
B5
JBossRMIClassLoader#bc450b
B6
JBossRMIClassLoader#bc450b
C1
UnifiedClassLoader3#a45bc3
C2
UnifiedClassLoader3#a45bc3
C3
UnifiedClassLoader3#a45bc3
C4
JBossRMIClassLoader#bc450c
C5
JBossRMIClassLoader#bc450c
C6
JBossRMIClassLoader#bc450c
file2.log (Similar patterns except the "C" set repeats the "A" set)
A1
UnifiedClassLoader3#d0357a
A2
UnifiedClassLoader3#d0357a
A3
UnifiedClassLoader3#d0357a
A4
JBossRMIClassLoader#191777e
A5
JBossRMIClassLoader#191777e
A6
JBossRMIClassLoader#191777e
B1
UnifiedClassLoader3#d0357b
B2
UnifiedClassLoader3#d0357b
B3
UnifiedClassLoader3#d0357b
B4
JBossRMIClassLoader#191777f
B5
JBossRMIClassLoader#191777f
B6
JBossRMIClassLoader#191777f
C1
UnifiedClassLoader3#d0357a
C2
UnifiedClassLoader3#d0357a
C3
UnifiedClassLoader3#d0357a
C4
JBossRMIClassLoader#191777e
C5
JBossRMIClassLoader#191777e
C6
JBossRMIClassLoader#191777e
And after processing you get file1_processed.log
A1
UnifiedClassLoader#1
A2
UnifiedClassLoader#1
A3
UnifiedClassLoader#1
A4
JBossRMIClassLoader#2
A5
JBossRMIClassLoader#2
A6
JBossRMIClassLoader#2
B1
UnifiedClassLoader#3
B2
UnifiedClassLoader#3
B3
UnifiedClassLoader#3
B4
JBossRMIClassLoader#4
B5
JBossRMIClassLoader#4
B6
JBossRMIClassLoader#4
C1
UnifiedClassLoader#5
C2
UnifiedClassLoader#5
C3
UnifiedClassLoader#5
C4
JBossRMIClassLoader#6
C5
JBossRMIClassLoader#6
C6
and file2_processed.log
A1
UnifiedClassLoader#1
A2
UnifiedClassLoader#1
A3
UnifiedClassLoader#1
A4
JBossRMIClassLoader#2
A5
JBossRMIClassLoader#2
A6
JBossRMIClassLoader#2
B1
UnifiedClassLoader#3
B2
UnifiedClassLoader#3
B3
UnifiedClassLoader#3
B4
JBossRMIClassLoader#4
B5
JBossRMIClassLoader#4
B6
JBossRMIClassLoader#4
C1
UnifiedClassLoader#1
C2
UnifiedClassLoader#1
C3
UnifiedClassLoader#1
C4
JBossRMIClassLoader#2
C5
JBossRMIClassLoader#2
C6
JBossRMIClassLoader#2

Resources