如何使用变量从一个列表中移除另一个列表的共同值
问题分析与修复方案
你的脚本存在几个关键问题,导致最后无法正确从targets.lst中移除所有predicted.lst里的内容:
1. 目录列表收集错误
第一个循环里,for i in ' */ '的引号会把*/当作单个字符串处理,而且用>写入文件会每次循环覆盖内容,正确的写法应该是:
for i in */; do echo "$i" >> list.lst done
或者更简洁的写法,直接一次性输出所有目录:
echo */ > list.lst
2. 变量赋值错误(核心问题)
你通过循环给$predicted和$targets赋值时,每次循环都会覆盖变量的内容,最终这两个变量只会保留文件的最后一行,而不是整个列表。这就是为什么最后grep -v "${predicted}" "${targets}"只能移除最后一个目录的原因。
3. 正确的实现方式
不需要把文件内容读入变量,直接用grep的-f选项指定排除列表文件即可,一步完成需求:
简化后的完整脚本
# 收集目录名并处理成predicted.lst echo */ | fmt -1 | sed 's:/::g' > predicted.lst # 从targets.lst中移除predicted.lst里的所有条目 grep -v -f predicted.lst targets.lst > targets2.lst
用sed实现的替代方案
如果想用sed,需要把predicted.lst的每一行转成sed的删除命令:
sed -f <(sed 's/^/\/^/;s/$\/d/' predicted.lst) targets.lst > targets2.lst
解释:
- 内层
sed把每个目录名转成/^目录名$/d的sed命令(精确匹配整行) - 外层sed执行这些命令,删除匹配的行
内容的提问来源于stack exchange,提问作者meh47336
相关产品推荐
相关产品推荐

