基于moved.txt名单批量更新master.txt中的文件路径并适配Python subprocess执行
基于moved.txt名单批量更新master.txt中的文件路径并适配Python subprocess执行
问题分析
你需要根据moved.txt中的人名列表,批量修改master.txt中对应人员的文件路径为当前工作目录,同时保留原文件的行顺序,还要能在Python的subprocess.run()中执行。之前的尝试因为没有正确处理原文件的所有行、未将修改内容写回原文件等问题,没能得到预期结果。
解决方案
这里提供两种可靠的实现方式,都能满足需求且适配Python subprocess:
方法1:使用sed + 进程替换(简洁高效,无临时文件)
这个方法通过将moved.txt转换为sed的修改命令,直接原地修改master.txt,同时保留原行顺序:
Shell命令示例
sed -i -f <(sed 's/^/\/^&\/ s|".*\/|"'"$(pwd)"'\/|;' moved.txt) master.txt
适配Python subprocess的代码
import os import subprocess folder = "/path/to/your/target/folder" # 替换为你的实际工作目录路径 working_dir = os.path.abspath(folder) # 构造sed命令,注意转义反斜杠以适配Python字符串 cmd = f''' sed -i -f <(sed 's/^/\\/^&\\/ s|".*\\/|"{working_dir}\\/|;' moved.txt) master.txt ''' # 执行命令 status = subprocess.run( cmd, cwd=folder, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL )
命令解释
- 进程替换
<(sed 's/^/\/^&\/ s|".*\/|"'"$(pwd)"'\/|;' moved.txt)会把moved.txt的每一行(比如Linda)转换成sed的修改命令:/^Linda/ s|".*/|"/workingdir/|,意思是匹配以Linda开头的行,将路径中"到最后一个/的部分替换为当前工作目录。 sed -i -f会读取这些动态生成的命令,直接原地修改master.txt。
方法2:使用awk(逻辑清晰,兼容性好)
如果你的系统中sed的进程替换特性不可用(比如某些老旧系统),可以用awk实现,通过临时文件过渡,逻辑更直观:
Shell命令示例
awk -v workdir="$(pwd)" ' BEGIN { # 把moved.txt的人名加载到数组中 while ((getline < "moved.txt") > 0) { names[$1] = 1 } } { # 判断当前行的人名是否在名单中 if ($1 in names) { # 替换路径部分:将"到最后一个/的内容换成工作目录 sub(/".*\//, "\"" workdir "/", $0) } # 输出行(修改后的或原行) print $0 } ' master.txt > master.tmp && mv master.tmp master.txt
适配Python subprocess的代码
import os import subprocess folder = "/path/to/your/target/folder" working_dir = os.path.abspath(folder) cmd = f''' awk -v workdir="{working_dir}" ' BEGIN {{ while ((getline < "moved.txt") > 0) {{ names[$1] = 1 }} }} {{ if ($1 in names) {{ sub(/".*\\//, "\"" workdir "/", $0) }} print $0 }} ' master.txt > master.tmp && mv master.tmp master.txt ''' status = subprocess.run( cmd, cwd=folder, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL )
命令解释
- 先将
moved.txt中的所有人名存入awk数组names。 - 遍历
master.txt的每一行,若行首人名在names数组中,就替换路径部分为当前工作目录;否则直接输出原行。 - 将所有输出写入临时文件,再替换原
master.txt(避免直接修改原文件时的意外损坏)。
为什么之前的尝试失败?
- 第一个命令仅输出修改后的匹配行,未处理原文件的其他行,也未写回原文件。
- 第二个命令同时处理管道输入和原文件,会输出修改后的行+原文件所有行,结果混乱且未写回原文件。
- 第三个命令的
sed -i未指定要修改的文件,无法将修改内容写回原文件,且丢失了未匹配的行。
注意事项
- 确保Python进程对
master.txt有读写权限,对工作目录有创建临时文件的权限。 - 若工作目录路径包含空格或特殊字符,两种方法中的路径都已用双引号包裹,能正确处理。
- 使用
os.path.abspath(folder)获取工作目录比shell的pwd更可靠,因为subprocess.run()的cwd参数会改变shell的工作目录,Python变量可提前计算准确路径。
备注:内容来源于stack exchange,提问作者David Robie
相关产品推荐
相关产品推荐

