0

I am reading a map file and writing the data in a column format to a text file. The code I wrote is below, but it does not do the work for me.

fo = open(filename, "r+")
fu = open("map.txt","w+")

for line in fo:
    if (".data.g" in line):
        fu.write(line)
        print line,

fo.close()
fu.close()

#to remove unwanted data
f = open("map1.txt", "w+")
g = open("map.txt", "r+")

for line in g:
    if((".data " in line) and (".bss" in line) and(".text" in line )):
        break
    else:
        f.write(line)
        f.write('\n')

f.close()
g.close()

The output expected is

    2007c04c .data  g_isr_array
    2007c004 .data  g_retry_count
    2007c000 .data  g_pkt_hist_wptr

The input map file is the format

.data          0x2007c000        0x0 G:/SJSUDev_V2/SJSU_Dev/projects/lpc1758_freertos_v2/_build/L4_IO/wireless/src/mesh.o
 .data.g_pkt_hist_wptr
                0x2007c000        0x4 G:/SJSUDev_V2/SJSU_Dev/projects/lpc1758_freertos_v2/_build/L4_IO/wireless/src/mesh.o
 .data.g_retry_count
                0x2007c004        0x1 G:/SJSUDev_V2/SJSU_Dev/projects/ lpc1758_freertos_v2/_build/L4_IO/wireless/src/mesh.o
 .data.g_our_node_id
                0x2007c005        0x1 G:/SJSUDev_V2/SJSU_Dev/projects/ lpc1758_freertos_v2/_build/L4_IO/wireless/src/mesh.o
 .data          0x2007c006        0x0 G:/SJSUDev_V2/SJSU_Dev/projects/ lpc1758_freertos_v2/_build/L4_IO/wireless/src/nrf24L01Plus.o
 .data          0x2007c006        0x0 G:/SJSUDev_V2/SJSU_Dev/projects/ lpc1758_freertos_v2/_build/L4_IO/wireless/src/wireless.o
 .data          0x2007c006        0x0 G:/SJSUDev_V2/SJSU_Dev/projects/ lpc1758_freertos_v2/_build/L4_IO/src/gpio.o
 .data          0x2007c006        0x0 G:/SJSUDev_V2/SJSU_Dev/projects/ lpc1758_freertos_v2/_build/L4_IO/src/io_source.o

I want to read only the global variable which starts with ".data.g" but the address is on the next line which my code is unable to read.

Benq
  • 13
  • 1
  • 1
  • 5
  • you will need to scan the next line when you find your .data.g line of interest. you can do so using iter() and next(). See my answer. – trans1st0r Apr 18 '16 at 20:57

2 Answers2

1

Here are some steps:

  1. Open your files using 'with'.

Using with

  1. For every line, scan the line[0:7] and compare with '.data.g' to see if it's the line you want. If yes, split the line with line.split() and extract the part after .data. by slicing the string. To get the address in the next line, you will need to move ahead one line. See this link on how to do it:

Python: For loop with files, how to grab the next line within forloop?

Once you have that line, do a string split and slice to get theaddress. With all three data items now, write to the file.

For any line the line[0:7] == '.data.g' criteria, skip ahead

Example:

with open('map.txt', 'r') as readF:
  with open('map1.txt', 'w') as writeF:
    for line in readF: 
       if line.startswith('.data.g'):
          try:         # next() can cause StopError, gotta catch it
            row = line.split()
            part_after_data = row[0][6:]
            line = next(ireadF)
            addr = line.split()[0]
            writeF.writeline(addr + ' .data '+ part_after_data )
          except:
            pass
Community
  • 1
  • 1
trans1st0r
  • 2,023
  • 2
  • 17
  • 23
  • 1
    FYI, the conversion step `ireadF = iter(readF)` is unnecessary; file-like objects are true iterators, not iterables; wrapping in `iter()` is harmless (the iterator protocol requires that `iter(iterator)` returns the original iterator), but unnecessary. Also, I'd use `if line.startswith('.data.g'):` instead of an explicit slice and equality check; explicit slice indices are dangerous, since a change in the target string requires changing the slice indices to match or you end up getting a guaranteed failure on every test. Easy to mess up during code maintenance. – ShadowRanger Apr 18 '16 at 21:04
1

If the data is in the format and order posted you really just want the first lines that don't start with .data:

from itertools import imap

with open("map.txt") as f:
    rows = imap(str.split, f)
    for row in rows:
        if row[0] != ".data":
            a, b = row[0].rsplit(".", 1)
            print(next(rows)[0],a, b)

Which using your input will give you:

('0x2007c000', '.data', 'g_pkt_hist_wptr')
('0x2007c004', '.data', 'g_retry_count')
('0x2007c005', '.data', 'g_our_node_id')

You can also use the lines starting with .data.:

from itertools import imap

with open("map.txt") as f:
    rows = imap(str.split, f)
    for row in rows:
        if row[0].startswith(".data."):
            a, b = row[0].rsplit(".", 1)
            print(next(rows)[0],a, b)

Which will give you the same result.

Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321