Linux bash中如何用for循环生成文件名排列实现多文件join操作
问题描述
现有3个文本文件A.txt、B.txt、C.txt,每个文件仅包含1列唯一字符串,需要对三个文件两两执行join操作,得到A-B、B-C、A-C三组两两组合的比对结果,实现排列组合效果的共有值提取。
示例参考
单独执行两两join的命令格式如下:
join -1 1 -2 1 A.txt B.txt > AB.txt
其余两组配对命令可参照上述格式修改参数。
测试用例数据
- A.txt内容:
100 101 102 104
- B.txt内容:
101 103 104 105
- C.txt内容:
100 103 104 105
预期输出
- A-B比对结果AB.txt内容为两个文件的共有值:
101 104
- A-C比对结果AC.txt内容:
100 104
- B-C比对结果BC.txt内容:
103 105
实现方案
可以通过两层嵌套的bash for循环自动遍历所有两两不重复的文件组合,自动生成对应输出文件,无需手动编写每条join命令,代码如下:
# 定义所有参与比对的文件名数组 files=("A.txt" "B.txt" "C.txt") file_count=${#files[@]} # 外层循环取第一个比对文件 for ((i=0; i<file_count; i++)); do # 内层循环从i的下一个位置开始取第二个比对文件,避免重复配对 for ((j=i+1; j<file_count; j++)); do file1=${files[$i]} file2=${files[$j]} # 自动拼接输出文件名,去除.txt后缀后拼接 output_name="${file1%.*}${file2%.*}.txt" # 执行join操作 join -1 1 -2 1 "$file1" "$file2" > "$output_name" done done
补充说明
如果你的原始输入文件未按字典序排序,可能会出现join漏匹配的情况,可以修改join命令为以下形式即可兼容未排序文件:
join -1 1 -2 1 <(sort "$file1") <(sort "$file2") > "$output_name"
后续如果需要新增更多文件参与两两比对,只需要在files数组中添加对应的文件名即可,无需修改循环逻辑。
内容的提问来源于stack exchange,提问作者Paulo Alvarez
相关产品推荐
相关产品推荐

