내 연장을 위해이전 질문, 다음 형식의 IP 범위 목록이 있습니다.
Long description:20.1.1.0-20.1.1.14
Another description:5.5.5.0-5.5.5.100
Yet another description:20.1.1.0-20.1.1.40
중복된 항목은 없지만 중복되는 IP 범위를 제거하고 싶습니다.
예를 들어 위의 예에서는 첫 번째 행의 범위가 이미 세 번째 행에 포함되어 있으므로 삭제해야 합니다.
노트:IP 범위뿐만 아니라 전체 행(설명 포함)을 유지해야 합니다.
답변1
입력 줄 재정렬에 문제가 없다면 GNU Awk와 "sort" 명령을 사용하는 비교적 간단한 해결책이 있습니다. 기본 아이디어는 IP 주소를 포인트 쌍 대신 단일 숫자로 변환하여 비교를 매우 쉽게 만들고 -k
특정 필드에서만 정렬하도록 지정할 수 있는 정렬 플래그를 사용하는 것입니다.
간결성을 위해 이는 공동 처리의 GNU awk 기능도 사용하므로 다음을 사용하기 전후에 데이터를 매우 쉽게 처리할 수 있습니다 sort
.
편집하다:이 답변의 원래 버전에 있는 명령줄은 sort
약간 잘못되었습니다. sort -k2,3r
필드 합계는 실제로 단일 2
키로 처리되어 3
역순으로 정렬되었습니다. 먼저 필드별로 정렬 하고 (역방향) 필드를 순위결정자로 사용하여 sort -k2,2n -k3,3rn
필요한 작업을 수행합니다 .2
3
# Run as: gawk -F: -f <thisfile.awk> <input file>
BEGIN {
# Define the sort command that we will be using later as a variable
# Sort by
# - the 1st ip, smallest-to-largest
# - the 2nd ip, largest-to-smallest
sort="sort -n -t: -k2,2n -k3,3nr";
}
# For every line:
{
# Store the individual components of the addresses into 'ips'
match($2, /([[:digit:]]+).([[:digit:]]+).([[:digit:]]+).([[:digit:]]+)\
-([[:digit:]]+).([[:digit:]]+).([[:digit:]]+).([[:digit:]]+)/, ips);
# Add the components together to get the IPs as a single number.
# The print also uses : as the delimiter between the 2 IPS for simplicity
print $1":"ips[4]+256*(ips[3]+256*(ips[2]+256*ips[1])) \
":"ips[8]+256*(ips[7]+256*(ips[6]+256*ips[5])) \
|& sort
}
# After sending all lines to sort in the appropriate format
END {
# Close sort's input stream, so that we can read its output
close(sort, "to");
# Keep track of the upper end of the previous range
prevHigh=0;
# Read & field-split all lines from sort's output
while((sort |& getline) > 0) {
# One range is contained in another if its low address is >= the
# other's (guaranteed by the sort command) and its high address is <=
# the other's. So, we should print this record when its high address is >
# prevHigh:
if ($3 > prevHigh) {
print $1":"int($2/(256*256*256))%256"."int($2/(256*256))%256"." \
int($2/256)%256"."$2%256 \
"-"int($3/(256*256*256))%256"."int($3/(256*256))%256"." \
int($3/256)%256"."$3%256 \
# This is now the previous range
prevHigh = $3
}
}
}