如何在Bash中正确遍历两个长度不等的文件?
Bash脚本实现作业与主机的一一对应SQL生成
我是Bash脚本新手,正在编写一个生成SQL语句列表的脚本,需求如下:
- 有两个文件:
avail_hosts.log(可用主机列表)和archiv_jobs.log(作业列表),文件长度不相等 - 生成的每条SQL语句包含唯一作业和唯一主机
- 所有作业必须分配到主机,单个作业和主机只能被分配一次
- 作业分配完成后,剩余主机可忽略,且作业数量不会超过主机数量
文件内容
$ cat avail_hosts.log computer1 computer2 computer3 computer4 computer5 $ cat archiv_jobs.log job1 job2 job3 job4 job5
当前脚本问题
我当前的脚本无法实现主机值的递增,导致所有作业都对应同一个主机:
#! /bin/bash rm ~/logs/assign_hosts.sql sql_script=~/logs/assign_hosts.sql host=~/logs/avail_hosts.log for n in $(cat ~/logs/archiv_jobs.log) do for h in $(cat ~/logs/avail_hosts.log) do host=$h done printf "UPDATE pw_batch_app.job_control SET host_name = $host WHERE job_name='$n';\n" >> $sql_script done
当前输出
UPDATE pw_batch_app.job_control SET host_name = computer1 WHERE job_name='Job1'; UPDATE pw_batch_app.job_control SET host_name = computer1 WHERE job_name='Job2'; UPDATE pw_batch_app.job_control SET host_name = computer1 WHERE job_name='job3'....
期望输出
UPDATE pw_batch_app.job_control SET host_name = computer1 WHERE job_name='Job1'; UPDATE pw_batch_app.job_control SET host_name = computer2 WHERE job_name='Job2'; UPDATE pw_batch_app.job_control SET host_name = computer3 WHERE job_name='job3'....
我尝试添加((h++))但没有效果:
for n in $(cat ~/logs/archiv_jobs.log) do for h in $(cat ~/logs/avail_hosts.log) do host=$h ((h++)) done printf "UPDATE pw_batch_app.job_control SET host_name = $host WHERE job_name='$n';\n" >> $sql_script done
解决方案(来自@merof)
i=0 for host in $(cat avail_hosts.log) do # 获取对应序号的作业,同时去除行尾空格 n=$(sed -n "$((i+1))p" archiv_jobs.log | sed 's/ *$//') # 如果没有更多作业,退出循环 if [ -z "$n" ]; then break fi printf "UPDATE pw_batch_app.job_control SET host_name = $host WHERE job_name='$n';\n" >> str.tql ((i++)) done
逻辑说明
- 初始化计数器
i为0,用于匹配作业的行号 - 遍历每个主机,通过
sed获取对应行号的作业(行号从1开始,所以用i+1) - 检查是否获取到作业,若为空则退出循环,避免无效分配
- 生成对应的SQL语句并写入文件,然后计数器自增,匹配下一个作业
内容的提问来源于stack exchange,提问作者RyanAcevedo
相关产品推荐
相关产品推荐

