python 如何在目录和子目录中搜索/替换文本[重复]

vjrehmav  于 2023-09-29  发布在  Python
关注(0)|答案(4)|浏览(98)

此问题已在此处有答案

Recursively find and replace string in text files(10个答案)
昨天关门了。
我找了又找,但还没有找到一个简单的解决办法。很多完整的教程和博士论文,但我不想读一页页的东西。

**我想在一个目录中的所有文件和子目录中搜索和替换一个文本项。**我有一段代码,可以通过使用以下os.scandir()参数之一在父目录中的选定文件和所有文件中搜索和替换:

  1. '.'
  2. os.getcwd()
  3. ()

(They得到相同的结果-只替换父目录中的内容,而不替换子目录或文本文件中的内容。我要替换所有指定的文本项字符串/text。)

**澄清:**它适用于任何选定的文件,但不适用于 * 不在 * 父目录中的项目。

我有一个包含Python代码、文本文件和子目录(文件夹)的目录,子目录包含更多的文本文件和更多的子目录。当然,我已经调整和调整,但我没有得到我想要的(虽然,我知道这很简单...)
这棵树看起来像这样:

下面是一段相关代码:

  1. if(FLAG_Option == 2):
  2. with os.scandir( ) as directory: # was '.' and theDIR, hum
  3. for item in directory:
  4. if not item.name.startswith('.') and item.is_file():
  5. with open(item, mode="r+") as file:
  6. data = file.read()
  7. # print(data) # Before text replaced
  8. data = data.replace(search_text, replace_text)
  9. file.write(data)
  10. print(data) # After text is replaced
  11. with open(item, mode="w") as file:
  12. file.write(data)
mm5n2pyu

mm5n2pyu1#

下面的代码将做你想要的。

  1. import os
  2. def scan_dir(root_dir, search_text, replace_text):
  3. if os.path.exists(root_dir) and os.path.isdir(root_dir):
  4. tree_paths = [os.path.join(dirs, files[-1]) for dirs, name, files in os.walk(root_dir, topdown=True, followlinks=False)]
  5. for file in tree_paths:
  6. with open(file, 'r+') as f:
  7. content = f.read()
  8. content = content.replace(search_text, replace_text)
  9. f.write(content)
  10. else:
  11. return
  12. root_path = 'C:\Training\Data'
  13. search_txt = 'python'
  14. replace_txt = 'text'
  15. scan_dir(root_path, search_text, replace_txt )

更新

os.walk()为每次迭代返回三个路径值的元组。directory pathdirectory name以及当前目录中每个files的列表。所以for eachwalk这个方法会产生一个或多个文件名。当一个目录或子目录中有多个文件时,上述代码无法访问每个文件。下面的代码可以解决这个问题。

  1. import os
  2. def scan_dir(root_dir, search_text, replace_text):
  3. if os.path.exists(root_dir) and os.path.isdir(root_dir):
  4. for dirs, name, files in os.walk(root_dir, topdown=True, followlinks=False):
  5. for file in files:
  6. content = None
  7. if not file.startswith('.'):
  8. current_item = os.path.join(dirs, file)
  9. with open(current_item, 'r') as f:
  10. content = f.read()
  11. content = content.replace(search_text, replace_text)
  12. with open(current_item, 'w') as b_file:
  13. b_file.write(content)
  14. else:
  15. return
  16. root_path = 'C:\\Training\\Data'
  17. search_txt = 'text'
  18. replace_txt = 'python'
  19. scan_dir(root_path, search_txt, replace_txt)

我已经测试了多个文件在一个目录和子目录的深度达3个子目录。我还测试了一个以上的子目录,每个子目录包含自己的子目录等情况。
我的目录结构如下所示

  1. C:\Training\Data root directory
  2. |
  3. root1.txt
  4. root2.txt
  5. sub sub directory
  6. |
  7. sub1.txt
  8. sub2.txt
  9. sub2 sub directory
  10. |
  11. sub21.txt
  12. sub22.tx
  13. sub3 first sub directory
  14. |
  15. sub31.txt
  16. sub32.txt
  17. sub4 second sub directory
  18. |
  19. sub41.txt
  20. sub42.txt
展开查看全部
busg9geu

busg9geu2#

你可以用os.walk遍历目录和子目录:

  1. import os
  2. def replace_text_in_files(rootdir, search_text, replace_text):
  3. for subdir, dirs, files in os.walk(rootdir):
  4. for file in files:
  5. if file.endswith('txt'):
  6. file_path = os.path.join(subdir, file)
  7. with open(file_path, 'r', encoding='utf-8') as f:
  8. data = f.read().replace(search_text, replace_text)
  9. with open(file_path, mode='w') as f:
  10. f.write(data)
  11. replace_text_in_files(r'D:\PROGRAMMING\temp\so\76936763', 'aaa', 'bbb')
nfeuvbwi

nfeuvbwi3#

在查找父目录时,如果项目是目录,则只需递归调用子目录上的函数。

  1. def search_directory(dir):
  2. ...
  3. for item in directory:
  4. if ... and item.is_file():
  5. ...
  6. elif item.is_dir():
  7. search_dirctory(item)
rqcrx0a6

rqcrx0a64#

感谢所有的帖子。我玩了所有这些,虽然不同的方面产生了部分解决方案,但其中一个(完整/完整的代码,未发布)做了我所需要的,只要沿着目录和子目录的文件/内容前进。
而且它要干净/简单得多...添加搜索/替换是容易的部分;所以,下面是代码到需要搜索/替换的部分。
我将包括特定的文件类型不采取行动(在条件语句)。

  1. import os
  2. dirpath = 'the_path_to_the_desired_DIR'
  3. for dirpath, dirnames, files in os.walk('.'):
  4. print(f'Found directory: {dirpath}')
  5. for file_name in files:
  6. print(file_name)

相关问题