根据文件中的第二个字段对 IP 地址进行排序

根据文件中的第二个字段对 IP 地址进行排序

在我的 ksh 脚本中,我需要添加以下任务(操作系统 - linux/solaris )

我有以下文件

 more test.txt


 /etc/backup/app 172.1.120      172.110.120 
 /etc/backup/app 172.1.120.12   172.110.120.98 
 /etc/backup/app 192.1.120      192.120.120 
 /etc/backup/app 172.1.120.1      172.110.120.7 
 /var/log/df     193.23.2       193.23.2
 /var/log/df     193.23.2.111   193.23.2.159

如何找到所有IP4 个八位位组在文件的开头,然后是其他IP3 个八位位组

备注 – IP 将根据第二个字段进行排序

请求文件的示例(排序后)

    more test.txt

    /etc/backup/app 172.1.120.12   172.110.120.98 
    /etc/backup/app 172.1.120.1    172.110.120.7
    /var/log/df     193.23.2.111   193.23.2.159
    /etc/backup/app 172.1.120      172.110.120 
    /etc/backup/app 192.1.120      192.120.120 
    /var/log/df     193.23.2       193.23.2

解决方案可以使用 sort 或 ksh/awk/sed/perl oneliner ...等来完成

答案1

假设您GNU awk这里有您需要的一行:

$ awk '{n=split($2,ip,".");if(n==4)print $0;else a[$2]=$0}END{n=asorti(a,b);for(i=1;i<=n;i++)print a[b[i]]}' file
/etc/backup/app 172.1.120.12   172.110.120.98 
/etc/backup/app 172.1.120.1    172.110.120.7 
/var/log/df     193.23.2.111   193.23.2.159
/etc/backup/app 172.1.120      172.110.120 
/etc/backup/app 192.1.120      192.120.120 
/var/log/df     193.23.2       193.23.2

答案2

awk '{printf "%s.,%s\n", $2, $0}' | \
sed -E -e 's/^(([0-9]+\.){4}),/0.\1,/' -e 's/^(([0-9]+\.){3}),/1.\1,/' | \
sort -t. -k 1,1 -k 3,3 | \
sed -E -e 's/^[^,]+,//'`

这个想法是:

  1. 将相关字段复制到每行的开头并添加特殊分隔符(在本例中为逗号)
  2. 用于sed在前面添加一些值,该值取决于 IP 地址中的八位位组数量(我使用 0 表示 4 个八位位组,1 表示 3 个八位位组)
  3. 对相关字段的值进行排序
  4. 删除我们添加的所有内容

答案3

cat <(awk '{if($2~/[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*/){print $0}}' test.txt | sort -k 2) <(awk '{if($2~/^[0-9]*\.[0-9]*\.[0-9]*$/){print $0}}' test.txt | sort -k 2)
  • 匹配第二个字段有 4 个八位字节的行并排序
  • 匹配第二个字段在 3 个八位字节后结束的行并排序
  • 将两个结果连接在一起

相关内容