1

I have list of string from which i want to extract channel number value with low SIG value. Below is mt list name "Outlines"

Flags: A - active, P - privacy, R - routeros-network, N - nstreme, T - tdma,
W - wds, B - bridge
       ADDRESS           SSID        CHANNEL   SIG   NF SNR RADIO-... ROUTER...
AP     20:B5:C6:F1:B6:B0 INAPHDBD... 5815/2... -78  -60 -18
       52:4F:54:43:4F:44 P2MPRWXX... 5835/20/a -80 -102  22
A      52:41:44:57:49:4E             5835/20/a -86 -102  16
APR  B 4C:5E:0C:BF:EE:6E iBw         5865/2... -75 -102  27 4C5E0C... 6.38.5
A      00:19:70:2C:FD:82 TR6SL5      5835/20/a -86 -102  16
       20:B5:C6:F0:E6:F7             5855/20/a -58 -103  45

Below is the code i tried, but didnt know how i can iterate when line starts without blank or any other random value.

RSSI = ''
Myindex = [l for l, elem in enumerate (outlines) if 'AP' in elem]
#Myindex = [elem for elem in outlines if 'AP' in elem]


#RSSI =int('nan')
for ind in Myindex:
    newchannel = " ".join(outlines[ind].split()).split(' ')[3]
    newRSSI = " ".join(outlines[ind].split()).split(' ')[4]
    if RSSI < newRSSI or RSSI == '':
        RSSI =newRSSI
        channel = newchannel.split('/')[0]
       
print(channel)        
1

2 Answers 2

2

You can get the positions in each line you need to parse from the line that contains 'SIG' and 'CHANNEL'.

You can loop all lines, extract the positions and convert the SIG to a number and put it into a dictionary of lists of CHANNELS (if 2 have the same SIG and both are lowest).

You can proceed to work with the dictionary data:

t = """Flags: A - active, P - privacy, R - routeros-network, N - nstreme, T - tdma,
W - wds, B - bridge
        ADDRESS           SSID        CHANNEL   SIG   NF SNR RADIO-... ROUTER...
AP     20:B5:C6:F1:B6:B0 INAPHDBD... 5815/2... -78  -60 -18
        52:4F:54:43:4F:44 P2MPRWXX... 5835/20/a -80 -102  22
A      52:41:44:57:49:4E             5835/20/a -86 -102  16
APR  B 4C:5E:0C:BF:EE:6E iBw         5865/2... -75 -102  27 4C5E0C... 6.38.5
A      00:19:70:2C:FD:82 TR6SL5      5835/20/a -86 -102  16
        20:B5:C6:F0:E6:F7             5855/20/a -58 -103  45
"""

sigstart = 0
channelstart = 0
data = {}
for line in t.split("\n"):
    # find position of SIG and CHANNEL, ignore everything until we have that
    if sigstart == 0:
        try:
            sigstart = line.index("SIG")
            channelstart = line.index("CHANNEL")
        except ValueError:
            pass
        continue

    # parse line if long enough and has AP in it
    if len(line)>= sigstart+3 and "AP" in line:
        sig = int(line[sigstart:sigstart+3].strip())
        channel = line[channelstart:sigstart].strip()
        # add to dictionary - could use defaultdict if perfomance is an issue
        # but for the example this works just fine
        data.setdefault(sig,[]).append(channel)

# output all parsed data, sorted:
for sig,channel in  sorted(data.items(), key = lambda x:x[0]):
    print(sig, ', '.join(c.split("/")[0] for c in channel))

Output:

-78 5815  # lowerst, only 1 item
-75 5865

The very lowest would be sorted(data.items(), key = lambda x:x[0])[0].

Sign up to request clarification or add additional context in comments.

Comments

1

I figure out to extract the channel value having lowest SIG value using regex, regex are very power to use specially for a nasty data(list of strings). i used regex101 . com which makes life easier. below is the code i tried.

import re
outlines = """
Flags: A - active, P - privacy, R - routeros-network, N - nstreme, T - tdma,
W - wds, B - bridge
       ADDRESS           SSID        CHANNEL   SIG   NF SNR RADIO-... ROUTER...
AP     20:b5:C6:F1:B6:B0 INAPHDBD... 5815/2... -78  -60 -18
       52:4F:54:43:4F:44 P2MPRWXX... 5835/20/a -80 -102  22
A      52:41:44:57:49:4E             5835/20/a -86 -102  16
APR  B 4C:5E:0C:BF:EE:6E iBw         5865/2... -75 -102  27 4C5E0C... 6.38.5
A      00:19:70:2C:FD:82 TR6SL5      5835/20/a -86 -102  16
       20:b5:C6:F0:E6:F7             5855/20/a -58 -103  45
"""
regex = ".* ([0-9]+)\/[^ ]* ([-+0-9]*)[ ,]*"
        oldsig =''
        if __name__ == '__main__':
​
            for line in outlines:
                s = re.search(regex, line.replace('\r\n',''))
​
                if s:
                    channel = s.group(1)
                    sig = s.group(2)
                    if oldsig < sig or oldsig=='':
                        oldsig = sig
                        nchannel1 = channel
  
            print(nchannel1)

Which gives output

5835

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.