Hi
Please I need your help with this script.
I have an logfile.xml and I need to picks the file names of the path but not duplicate and writes them into a bat file, like copy %windiw&\system32\<filename> %1%

Output example for my .bat file should look like

copy %windiw&\system32\ dbghelp.dll  %1%
copy %windiw&\system32\ Riched32.dll  %1%
copy %windiw&\system32\ imm32.dll %1%

This is my Logfile.xml
<?xml version="1.0" encoding="UTF-8"?>
<Company>Sysinternals - www.sysinternals.com</Company>
<module>
<Timestamp>130412795960224800</Timestamp>
<BaseAddress>0x6de80000</BaseAddress>
<Size>24576</Size>
<Path>C:\Windows\system32\Riched32.dll</Path>
<Version>6.1.7600.16385 (win7_rtm.090713-1255)</Version>
<Company>Microsoft Corporation</Company>
<Description>Wrapper Dll for Richedit 1.0</Description>
</module>
<module>
<Timestamp>130412795960224800</Timestamp>
<BaseAddress>0x6f3b0000</BaseAddress>
<Size>65536</Size>
<Path>C:\Windows\system32\napinsp.dll</Path>
<Version>6.1.7600.16385 (win7_rtm.090713-1255)</Version>
<Company>Microsoft Corporation</Company>
<Description>E-mail Naming Shim Provider</Description>
</module>

The snippsat code

import os
import xml.etree.ElementTree as ET
tree = ET.parse("Logfile.xml")
root = tree.getroot()
for element in root.iter('Path'):
    file_name = os.path.basename(element.text)
     #.exe just an example that you can have more values
    if not file_name.endswith(('.exe', '.fmt', 'sys', 'tmp')):
        print element.text
    #print os.path.basename(element.text)

Ok
Where can I add copy %windiw&\system32\<filename> %1% in f_out.write ?

import os
import xml.etree.ElementTree as ET
f_out = open('my_file.txt', 'w')
tree = ET.parse("Logfile.xml")
root = tree.getroot()
for element in root.iter('Path'):
    file_name = os.path.basename(element.text)
     #.exe just an example that you can have more values
    if not file_name.endswith(('.exe', '.fmt', 'sys', 'tmp')):
        f_out.write('{}\n'.format(os.path.basename(element.text)))
f_out.close()

so that the out put will be

    copy %windiw&\system32\ dbghelp.dll %1%
    copy %windiw&\system32\ Riched32.dll %1%
    copy %windiw&\system32\ imm32.dll %1%

Edited 2 Years Ago by tony75

I think I have fixed it.
Is there another way to do it?

How can I remove duplicate file like?
copy %windir%\system32\sechost.dll %1%
copy %windir%\system32\sechost.dll %1%
copy %windir%\system32\sechost.dll %1%
copy %windir%\system32\sechost.dll %1%

import os
import xml.etree.ElementTree as ET
f_out = open('my_file.txt', 'w')
tree = ET.parse("Logfile.xml")
root = tree.getroot()
for element in root.iter('Path'):
    file_name = os.path.basename(element.text)
     #.exe just an example that you can have more values
    if not file_name.endswith(('.exe', '.fmt', 'sys', 'tmp')):
        #print 'copy %windir%\system32\', file_name, '%1%'
        f_out.write('copy %windiw&\system32\{}' ' %1%\n'.format(os.path.basename(element.text)))
f_out.close()

output
copy %windir%\system32\sechost.dll %1%
copy %windir%\system32\rpcrt4.dll %1%
copy %windir%\system32\oleaut32.dll %1%
copy %windir%\system32\ole32.dll %1%
copy %windir%\system32\comctl32.dll %1%
copy %windir%\system32\wow32.dll %1%
copy %windir%\system32\apphelp.dll %1%
copy %windir%\system32\shell32.dll %1%
copy %windir%\system32\shlwapi.dll %1%
copy %windir%\system32\sfc.dll %1%
copy %windir%\system32\sfc_os.dll %1%
copy %windir%\system32\comdlg32.dll %1%
copy %windir%\system32\version.dll %1%
copy %windir%\system32\userenv.dll %1%
copy %windir%\system32\profapi.dll %1%
copy %windir%\system32\imm32.dll %1%
copy %windir%\system32\msctf.dll %1%
copy %windir%\system32\uxtheme.dll %1%
copy %windir%\system32\sechost.dll %1%
copy %windir%\system32\sechost.dll %1%
copy %windir%\system32\sechost.dll %1%
copy %windir%\system32\sechost.dll %1%
copy %windir%\system32\sechost.dll %1%
copy %windir%\system32\sechost.dll %1%
copy %windir%\system32\comctl32.dll %1%
copy %windir%\system32\comctl32.dll %1%

Edited 2 Years Ago by tony75

This is a typical use case for generators and tools for iterables. Instead of writing to a file, use a generator

import os
import xml.etree.ElementTree as ET
from itertools import ifilterfalse

def generate_lines():
    tree = ET.parse("Logfile.xml")
    root = tree.getroot()
    for element in root.iter('Path'):
        file_name = os.path.basename(element.text)
        #.exe just an example that you can have more values
        if not file_name.endswith(('.exe', '.fmt', 'sys', 'tmp')):
            #print 'copy %windir%\system32\', file_name, '%1%'
            yield ('copy %windiw&\system32\{} %1%\n').format(
                os.path.basename(element.text))

Now, elimination of duplicates is a standard pattern. There is a generic solution at the end of itertools' module documentation

def unique_everseen(iterable, key=None):
    "List unique elements, preserving order. Remember all elements ever seen."
    # unique_everseen('AAAABBBCCDAABBB') --> A B C D
    # unique_everseen('ABBCcAD', str.lower) --> A B C D
    seen = set()
    seen_add = seen.add
    if key is None:
        for element in ifilterfalse(seen.__contains__, iterable):
            seen_add(element)
            yield element
    else:
        for element in iterable:
            k = key(element)
            if k not in seen:
                seen_add(k)
                yield element

We're ready to write the output file

with open('my_file.txt', 'w') as f_out:
    lines = unique_everseen(generate_lines())
    f_out.writelines(lines)

Edited 2 Years Ago by Gribouillis

This question has already been answered. Start a new discussion instead.