使用 for 循环查找文件差异以 bash 或 python 的特定字符串开头

Find File differences using for loop starts with specific string with bash or python

我正在尝试使用自动化脚本将 Linux 台机器添加到 ansible 主机文件中。自动化过程是;

1- Ansible 机器从其中一台 Vmware 服务器获取 Linux 名为 LinuxVms.txt 的 vm 列表。

2-我在下面开发了sh文件。它从 LinuxVms.txt 文件中将服务器添加到“[all_linux_host]”标签中。并且 sh 有效。 (一次操作)

经过这个过程,我要做的是;

Vmteam 会自动将 LinuxVm.txt 列表发送到 ansible 服务器,如果 LinuxVm.txt 文件有新的 IP 地址,我需要添加这个 IP 地址到 "[all_linux_host]" 标签下的 ansible 主机文件。

我认为 for 循环应该适用于此。 For循环必须控制新到达的LinuxVm.txt文件和只有[all_linux_host]标签(不是ansible主机文件中的所有标签) 如果文件和标签之间存在差异,它必须找到差异并添加到 "[all_linux_host]" 标签。

例如 LinuxVms.txt

1.1.1.1
2.2.2.2
3.3.3.3
12.12.12.12

当前的 ansible 主机文件 /etc/ansible/hosts.
[测试]
8.8.8.8
12.12.12.12
13.13.13.13

[all_linux_hosts] ## 这是 ansible 主机文件中的最后一个标签。.
1.1.1.1
2.2.2.2

for循环后,ansible主机文件必须是这样的

[测试]
8.8.8.8
12.12.12.12
13.13.13.13

[all_linux_hosts] ## IP地址顺序不输入.
1.1.1.1
2.2.2.2
3.3.3.3
12.12.12.12

你能帮我开发for循环吗?

一次操作

sudo cp /home/vmteam/LinuxVMs.txt /home/xxx
sudo chown xxx: /home/vmteam/LinuxVMs.txt
sudo dos2unix /home/xxx/LinuxVMs.txt
awk '{print }' /home/xxx/LinuxVMs.txt >> ansible_host_file  ##file correction
awk '{print }' /home/xxx/LinuxVMs.txt >> ansible_host_file  ##file correction
sed -i 's/PublicIp//g'    /home/xxx/ansible_host_file
sed -i 's/-//g' /home/xxx/ansible_host_file
sed -i '/^\s*$/d' /home/xxx/ansible_host_file
sed -i 's/IpAddress1/ /g' /home/xxx/ansible_host_file
sed -i '/^\s*$/d' /home/xxx/ansible_host_file``` 

这可以分三个阶段实现:

ips=$(awk 'NR==FNR { map[]=1;next } map[]!=1 { print  }' <(sed -n '/^$/d;/^\[all_linux_hosts\]/,/^\[.*\]/{/^\[/!p}' ansible_host_file) linuxvms.txt)

首先从 linuxvms.txt 生成不在 /etc/ansible/hosts 中的 IP 地址列表(在 all_linux_hosts 标签下,通过 sed 命令实现)我们将其重定向到 awk 中使用 linuxvm.txt 和第一个输入 (NR==FNR),我们创建一个名为 map 的 ip 地址数组。对于第二个输入,我们检查每个 ip 地址,如果它不在 map 数组中,我们打印。结果输出被读入变量 ips

while read ipadd;
do 
   sed "/\[all_linux_hosts\]/a$ipadd" ansible_host_file;
done <<< "$ips"

我们最终在 ip 地址上循环并将地址附加到“[all_linux_hosts]”行下,这与原始要求略有不同,但不会影响 Ansible 执行。

此处给出了使用 awk 的一种方式。

awk '
  NR==FNR {a[];next}

  =="[all_linux_hosts]" {f=1}
  f && (  in a ) { delete a[] } 
  
{print} 

  END {
    for (host in a) print host
  }
' LinuxVms.txt /etc/ansible/hosts
[test]  
8.8.8.8         
12.12.12.12   
13.13.13.13

[all_linux_hosts]
1.1.1.1     
2.2.2.2
12.12.12.12
3.3.3.3