TransWikia.com

compare available list print number in next line

Unix & Linux Asked on December 17, 2021

I was able to extract numbers (ids) between pattern(Available for user: and Chosen by user:)and match if a particular user chose an id from what was available to him from list of ids

Available for user:75=1654 at Time=5504.09 
Chosen by user:75=1655

Available for user:10=1300 at Time=550.09
Available for user:10=1301 at Time=550.09
Available for user:10=1303 at Time=550.09
Chosen by user:10=1301

I used sed pattern given in reply to my question at compare available list with chosen ids in shell script

The sed pattern used was this

 /^Avail/{
    s/[^=]*=([^ ]*).*/1/;H
}
/^Chosen/{
    s/.*=//;G;h;x;y/n/,/
    s/,/ is ab in /;s/$/,/
    /(.*) is.*,1,/s/ab/pre/
    s/(ab|pre) in ,(.*),/1sent in 2/
    p;s/.*//;x
}

Now i have a file with globalID and localID added after line "Chosen by user:" i.e.

Available for user:75=1654 at Time=5504.09 
Chosen by user:75=1655
globalID=1000 localID=1655

Available for user:10=1300 at Time=550.09
Available for user:10=1301 at Time=550.09
Available for user:10=1303 at Time=550.09
Chosen by user:10=1301
globalID=1020 localID=1301 

Available for user:20=1400 at Time=550.09
Available for user:20=1501 at Time=550.09
Available for user:20=1503 at Time=550.09
Chosen by user:20=1503
globalID=1030 localID=1503

Now i want print globalID in each line for each match and no match in two seperate files, file1 and file2 .The output for file1 (match case) where globalID of an id selected from available list by particular user is stored as:

1020
1030

The output for file2 (no match case) where globalID of an id not selected from available list by particular user is stored as:

1000

I tried

sed -nrf script.sed input.txt  | grep absent -A1 > file2

and

sed -nrf script.sed input.txt | grep present -A1 > file1

but it does not give next line of source file instead it gives next line of sed script output.

One Answer

If we take the awk answer I posted to your previous question and tweak it to print the information when it hits an empty line or the end of file instead of when it hits the "Chosen" line (which I should have done in the first place but I was being lazy):

$ cat tst.awk
BEGIN { FS="[:= ]" }
NF {
    if ( $1 == "Chosen" ) {
        user = $4
        chosen = $5
    }
    else {
        avail[$5]
    }
    next
}
{ prt() }
END {
    prt()
    printf "%d users chose available %d times and not available %d timesn", userCnt, availCnt, notAvailCnt
}

function prt() {
    if ( chosen in avail ) {
        availCnt++
        str = ""
    }
    else {
        notAvailCnt++
        str = " not"
    }
    userCnt++
    printf "User %s chose %s which was%s availablen", user, chosen, str
    delete avail
}

Then running it against your new input produces:

$ awk -f tst.awk file
User 75 chose 1655 which was not available
User 10 chose 1301 which was available
User 20 chose 1503 which was available
3 users chose available 2 times and not available 1 times

We can then tweak it to also print the globalID:

$ cat tst2.awk
BEGIN { FS="[:= ]" }
NF {
    if ( $1 == "Chosen" ) {
        user = $4
        chosen = $5
    }
    else if ( $1 == "globalID" ) {
        globalID = $2
    }
    else {
        avail[$5]
    }
    next
}
{ prt() }
END {
    prt()
    printf "%d users chose available %d times and not available %d timesn", userCnt, availCnt, notAvailCnt
}

function prt() {
    if ( chosen in avail ) {
        availCnt++
        str = ""
    }
    else {
        notAvailCnt++
        str = " not"
    }
    userCnt++
    printf "User %s chose %s which was%s available, and had globalID %sn", user, chosen, str, globalID
    delete avail
}

which outputs:

$ awk -f tst2.awk file
User 75 chose 1655 which was not available, and had globalID 1000
User 10 chose 1301 which was available, and had globalID 1020
User 20 chose 1503 which was available, and had globalID 1030
3 users chose available 2 times and not available 1 times

Hopefully you can see how easy it'd be to just change the print statements to print whatever you actually want to be output (and please don't pipe it to grep or anything else - just do it in awk, it's easy). For example:

$ cat tst3.awk
BEGIN { FS="[:= ]" }
NF {
    if ( $1 == "Chosen" ) {
        user = $4
        chosen = $5
    }
    else if ( $1 == "globalID" ) {
        globalID = $2
    }
    else {
        avail[$5]
    }
    next
}
{ prt() }
END { prt() }

function prt() {
    if ( chosen in avail ) {
        result = "match"
    }
    else {
        result = "nomatch"
    }
    if ( target == result ) {
        print globalID
    }
    delete avail
}

.

$ awk -v target='match' -f tst3.awk file
1020
1030

$ awk -v target='nomatch' -f tst3.awk file
1000

Answered by Ed Morton on December 17, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP