Bash Shell中基于公共列合并文件(禁用join、保原序)的方案咨询
按原顺序合并文件并转换布尔值的Linux命令方案
针对你需要严格保持file1.txt中国家顺序的合并与布尔值转换需求,这里有几个实用的Linux命令方案,完全避开会自动排序的join命令:
1. 用Awk一次性完成合并与转换(推荐)
Awk是处理这类文本匹配任务的利器,它可以先把file2.txt的内容存入内存的关联数组,再按file1.txt的顺序输出结果,同时完成TRUE/FALSE到1/0的转换,一步到位:
NR==FNR { map[$1] = $2; next } { print $0, (map[$0] == "TRUE" ? 1 : 0) } file2.txt file1.txt
命令解释:
NR==FNR:这个条件只在处理第一个输入文件(file2.txt)时成立,此时我们把每个国家作为键,对应的TRUE/FALSE值作为值存入map数组。next:跳过后续处理,直接读取下一行,确保file2.txt的内容只被用来填充数组。- 处理
file1.txt时,每一行(国家名称)对应输出该行,再根据map里的对应值,把TRUE转为1,FALSE转为0。
执行后直接输出最终想要的结果:
USA 0
Italy 1
Canada 0
France 0
2. 分两步实现:先合并,再转换
如果你希望先得到中间的合并结果(带TRUE/FALSE的版本),再进行转换,可以拆分操作:
第一步:按顺序合并两个文件
用Awk生成中间文件:
NR==FNR { status_map[$1] = $2; next } { print $0, status_map[$1] } file2.txt file1.txt > merged.txt
这一步会生成你要的中间输出merged.txt:
USA FALSE
Italy TRUE
Canada FALSE
France FALSE
第二步:转换布尔值为数字
用Sed替换文本:
-e参数用来指定多个替换规则,分别把行尾的TRUE换成1,FALSE换成0,最终得到目标结果。
3. Bash循环结合Grep(适合小文件)
如果文件规模不大,也可以用Bash循环逐行处理file1.txt,配合Grep匹配file2.txt中的对应行:
while read country; do # 精准匹配file2中以该国家开头的行,提取状态值 status=$(grep "^${country} " file2.txt | awk '{print $2}') # 转换布尔值 converted=$(echo "$status" | sed 's/TRUE/1/; s/FALSE/0/') # 输出结果 echo "${country} ${converted}" done < file1.txt > final.txt
注意:
这个方法的缺点是每次循环都要遍历file2.txt一次,当文件很大时效率会很低,因此更适合处理小型文本文件。
内容的提问来源于stack exchange,提问作者Paolo Lorenzini
相关产品推荐
相关产品推荐

