如何删除File2.txt中非File1.txt前缀的行并实现原地编辑?
解决方案:用File1的前缀过滤File2(优先原地编辑)
方法1:GNU awk 原地编辑(推荐)
GNU awk 4.1及以上版本支持-inplace参数直接原地编辑,无需额外临时文件操作:
awk -v inplace=1 'NR==FNR {prefixes[$0]; next} {for(p in prefixes) if(index($0,p)==1) {print; next}}' File1.txt File2.txt
- 逻辑:先读取File1的所有前缀字符串存入数组,再遍历File2的每一行,判断行首是否匹配数组中的任意前缀,匹配则保留输出。
- 兼容旧版awk(无
-inplace):
awk 'NR==FNR {prefixes[$0]; next} {for(p in prefixes) if(index($0,p)==1) {print; next}}' File1.txt File2.txt > temp.txt && mv temp.txt File2.txt
方法2:sed 原地编辑(需处理前缀模式)
先将File1的每行转换为^前缀的正则格式,拼接成匹配模式后传给sed做原地删除:
# 生成匹配模式(若前缀含正则特殊字符,需先转义) PATTERN=$(sed 's/[.*+?^${}()|[\]\\]/\\&/g; s/^/^/' File1.txt | tr '\n' '|' | sed 's/|$//') # GNU sed 原地编辑 sed -i "/$PATTERN/!d" File2.txt # macOS sed 需加空参数 # sed -i '' "/$PATTERN/!d" File2.txt
- 逻辑:
/模式/!d表示删除不匹配模式的行,实现保留符合前缀的行。
方法3:grep + 临时文件替换
利用grep的-f参数读取前缀模式,结合进程替换或临时文件实现过滤:
# 用进程替换直接生成前缀模式(bash/zsh支持) grep -f <(sed 's/^/^/' File1.txt) File2.txt > temp.txt && mv temp.txt File2.txt # 兼容sh shell的写法 sed 's/^/^/' File1.txt > patterns.txt grep -f patterns.txt File2.txt > temp.txt && mv temp.txt File2.txt && rm patterns.txt
内容的提问来源于stack exchange,提问作者navig8tr
相关产品推荐
相关产品推荐

