python - guia - Copiando líneas seleccionadas de archivos en diferentes directorios a otro archivo
qgis manual (4)
Tengo un directorio con muchos subdirectorios, que contienen archivos. Quiero abrir los archivos que terminan con "root.vrpj" o "root.vprj", en la carpeta "App_integrations" y copiar las líneas que contienen la palabra "table" a otro archivo.
Hasta ahora he logrado visitar cada archivo con este código:
for root, dirs, files in os.walk(movedir):
for filename in files:
if filename.endswith(("root.vrpj", "root.vprj")):
El problema es que lo que tengo ahora son solo los nombres de los archivos que quiero visitar y estoy atrapado aquí.
Esta es una versión del código de Ajax que cierra los archivos que abre en el ciclo (y corrige algunos otros problemas menores):
with open(''final_file.txt'', ''w'') as f:
for root, dirs, files in os.walk(movedir):
for filename in files:
if filename.endswith(("root.vrpj"), ("root.vprj")):
with open(os.path.join(root, filename)) as finput:
for line in finput:
if ''table'' in line:
f.write(line)
sin embargo, cuando ve 8 niveles de sangría, necesita refactorizar, por ejemplo:
def find_files(startdir, *extensions):
for root, dirs, files in os.walk(movedir):
for filename in files:
if filename.endswith(extensions):
yield os.path.join(root, filename)
def find_lines(fname, text):
with open(fname) as fp:
return [line for line in fp if text in line]
with open(''final_file.txt'', ''w'') as f:
for fname in find_files(movedir, ''root.vrpj'', ''root.vprj''):
f.writelines(find_lines(fname, ''table''))
Puedes intentar esto:
f = open(''final_file.txt'', ''w'')
for root, dirs, files in os.walk(movedir):
for filename in files:
if filename.endswith("root.vrpj") or filename.endswith("root.vprj"):
with open(filename) as data:
for line in data:
if "table" in data:
f.write(''{}/n''.format(data))
f.close()
Encuentra los archivos
from pathlib import Path
import itertools
source_dir = Path(<source_dir>)
patterns = [''**/*root.vrpj'', ''**/*root.vprj'']
files = itertools.chain.from_iterables(source_dir.glob(pat) for pat in patterns))
Filtra los archivos:
def filter_lines(files):
for file in files:
if not ''App_Integration'' in file.parts:
continue
with file.open(''r'') as file_handle:
for line in file_handle:
if ''table'' in line:
yield line
Escribe la salida
def save_lines(lines, output_file=sys.std_out):
for line in lines:
output_file.write(line)
with Path(<output_file>).open(''w'') as output_file:
save_lines(filter_lines(files), as output_file)
Finalmente lo resolví
import os
rootdir = my root folder
# creates a file f that contains all the lines of the files
# with "root.vrpj" or "root.vprj" in their name
# and who are inside "App_integrations" folders
# without duplicates
#creating the big file with all the file containing the lines I need
f = open(''final_file.txt'', ''a'')
for root, dirs, files in os.walk(rootdir):
for filename in files:
if (filename.endswith(("root.vrpj", "root.vprj")) and ("App_Integration" in os.path.join(root, filename))):
full_name = os.path.join(root, filename)
data = open(full_name).read()
f.write(data + "/n")
f.close()
#copying the lines I need to f1 without duplicates
lines_seen = set()
f = open(''final_file.txt'')
f1 = open(''testread1.txt'', ''a'')
doIHaveToCopyTheLine=False
for line in f.readlines():
if (("Table" in line) and (line not in lines_seen)):
doIHaveToCopyTheLine=True
if doIHaveToCopyTheLine:
f1.write(line)
lines_seen.add(line)
f1.close()
f.close()