ยกเว้น IP จากช่วงเพื่อหลีกเลี่ยงความขัดแย้ง


0

ฉันมีรายการ IP และช่วงที่ยาวและฉันต้องการดีบักรายการของฉันลบ IP ที่สร้างความขัดแย้งด้วย CIDR .

ตัวอย่างเช่น:

8.8.8.0/24
8.8.8.8
23.236.62.147
23.236.48.0/20
104.154.76.93
104.154.0.0/15
etc

ดังนั้นฉันต้องลบ 23.236.62.147 (เพราะเป็น subnetwork ของ 23.236.48.0/20 ) 104.154.76.93 (เพราะเป็น subnetwork ของ 104.154.0.0/15 ) 8.8.8.8 (เพราะเป็นเครือข่ายย่อยของ 8.8.8.0/24 ) ฯลฯ ฯลฯ

วิธีทำใน bash / command linux


ดังนั้นสิ่งที่คุณต้องการทำจริงๆคือลบ ซ้ำซาก รายการ.
Daniel B

รายการ (ips) ที่ขัดแย้งกับช่วง CIDR

คุณมีสิทธิ์เข้าถึง Python หรือต้องทำใน Bash เท่านั้นหรือไม่
Robbie Crash

โดยเฉพาะอย่างยิ่งในทุบตี แต่ถ้าหลามทำงาน ....

โปรดทราบว่า superuser.com ไม่ใช่บริการเขียนสคริปต์ / รหัสฟรี หากคุณบอกเราถึงสิ่งที่คุณได้ลองมาแล้ว (รวมถึงสคริปต์ / รหัสที่คุณใช้อยู่) และที่ที่คุณติดอยู่เราสามารถลองช่วยแก้ปัญหาเฉพาะ คุณควรอ่าน ฉันจะถามคำถามที่ดีได้อย่างไร .
DavidPostill

คำตอบ:


0

ด้วย bash และ GNU grep:

#!/bin/bash

common() {
  # From http://stackoverflow.com/a/35114656/3776858

  D2B=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})
  declare -i c=0                              # set integer attribute

  # read and convert IPs to binary
  IFS=./ read -r a1 a2 a3 a4 m <<< "$1"
  b1="${D2B[$a1]}${D2B[$a2]}${D2B[$a3]}${D2B[$a4]}"

  IFS=./ read -r a1 a2 a3 a4 m <<< "$2"
  b2="${D2B[$a1]}${D2B[$a2]}${D2B[$a3]}${D2B[$a4]}"

  # find number of same bits ($c) in both IPs from left, use $c as counter
  for ((i=0;i<32;i++)); do
    [[ ${b1:$i:1} == ${b2:$i:1} ]] && c=c+1 || break
  done    

  # create string with zeros
  for ((i=$c;i<32;i++)); do
    fill="${fill}0"
  done    

  # append string with zeros to string with identical bits to fill 32 bit again
  new="${b1:0:$c}${fill}"

  # convert binary $new to decimal IP with netmask
  new="$((2#${new:0:8})).$((2#${new:8:8})).$((2#${new:16:8})).$((2#${new:24:8}))/$c"
  echo "$new"
}


cidr="$1"

# using process substitution
grep -vxFf <(
  grep -v / "$cidr" | while IFS= read -r ip1; do
    grep / "$cidr" | while IFS=/ read -r ip2 mask2; do
      out=$(common "$ip2/$mask2" "$ip1/32")
      out_mask="${out#*/}"
      if [[ $out_mask -ge $mask2 ]]; then   # -ge: greater-than-or-equal
        echo "$ip1"
      fi
    done
  done
) "$cidr" > cidr_clean.txt

การใช้งาน: ./shadow.sh your_cidr_file.txt

ในไดเรกทอรีปัจจุบันของคุณคุณจะได้รับ cidr_clean.txt:

8.8.8.0/24
23.236.48.0/20
104.154.0.0/15

ขอบคุณมาก. ฉันขอขอบคุณอย่างยิ่งที่คุณปรับเปลี่ยนสคริปต์เพื่อให้ทำงานเฉพาะ. /shadow.sh (ไม่ใช่. / shadow.sh your_cidr_file.txt ใส่สคริปต์ your_cidr_file.txt ภายใน) ขอบคุณ

คุณต้องการที่จะเปลี่ยน cidr="$1" โดย cidr="your_cidr_file.txt"? หากไม่ใช่ความตั้งใจของคุณฉันขอแนะนำให้คุณเริ่มต้นคำถามใหม่ด้วยข้อกำหนดใหม่นี้
Cyrus

คุณคิดอย่างไรถ้าฉันแก้ไขสคริปต์นี้ของคุณ: grep -vxFf shadow.txt "$ cidr" | เรียง -u | เรียงลำดับ -t -k 1,1n -k 2,2n -k 3,3n -k 4,4n & gt; cidr_clean.txt

นั่นไม่ใช่ปัญหา ฉันลบไฟล์ shadow.txt ออกแล้ว
Cyrus

ฉันมีปัญหากับสคริปต์ของคุณ อาจใช้เวลาหลายชั่วโมง (อาจเป็นวันที่มีรายการ 3m ips) แม้ว่ารายการจะไม่มี CIDR หรือมีหนึ่งหรือสอง CIDR คุณสามารถเพิ่มกลไกการตรวจจับ CIDR เพื่อให้เร็วขึ้นได้ไหม ขอบคุณ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.