Score:14

ลบไฟล์หากตรงตามเงื่อนไขหลายข้อ

ธง ma

สิ่งที่ฉันต้องการ

ฉันมีสคริปต์ที่ดึงข้อมูลพอร์ตสำหรับโดเมนและจัดเก็บไว้ในไฟล์ข้อความที่เรียกว่า portscan.txt. ตัวอย่าง:

portscan.txt ไฟล์:

somedomain.com:80
somedomain.com:443

ฉันต้องการลบข้อมูลเมื่อตรงตามเงื่อนไขบางประการเท่านั้น เงื่อนไขเหล่านี้รวมถึง:

  • ไฟล์ที่มีโดเมนควรมี 2 บรรทัดหรือน้อยกว่า
  • พอร์ตควรเป็น 80 หรือ 443 เท่านั้น (เช่น ฉันไม่ต้องการลบไฟล์หากมีพอร์ต 8080, 8443 หรือพอร์ตอื่นๆ อยู่ในไฟล์)

บันทึก: โดยพื้นฐานแล้ว ไฟล์ตัวอย่างที่ให้ไว้ข้างต้น ควร ถูกลบ แต่ฉันไม่ต้องการลบไฟล์หากมี 2 บรรทัด แต่พอร์ตเป็น 8080 หรือ 8443 (หรือพอร์ตอื่นสำหรับเรื่องนั้น) ตัวอย่างดังนี้:

somedomain.com:8443
somedomain.com:443

สิ่งนี้ควร ไม่ ถูกลบ

สิ่งที่ฉันพยายาม

ฉันพยายามเขียนสคริปต์และนี่คือสิ่งที่ฉันมี:

#!/bin/bash

เส้น = $ (แมว portscan.txt | wc -l)
ports=$(cat portscan.txt | grep -Pv '(^|[^0-9])(80|443)($|[^0-9])')


ถ้า [[ $lines < 3 ]] && [[ $ports != 80 ]]; แล้ว
    ถ้า [[ $พอร์ต != 443 ]]; แล้ว
        echo "ฉันต้องการลบสิ่งนี้"
    ไฟ
อื่น
    echo "ฉันจะไม่ลบสิ่งนี้..."
ไฟ

นี่เป็นการเรนเดอร์สคริปต์ครั้งที่สอง ฉันพยายามซ้อน ถ้า เนื่องจากฉันไม่สามารถทำเงื่อนไขเช่นนี้:

ถ้า portscan.txt น้อยกว่าสองบรรทัด และ พอร์ตต่างๆ ไม่ 80 หรือ 443

ฉันยังพยายามทำสิ่งนี้ด้วยวิธีที่ง่ายกว่ามาก เช่น:

#!/bin/bash

เส้น = $ (แมว portscan.txt | wc -l)
ports=$(cat portscan.txt | grep -Pv '(^|[^0-9])(80|443)($|[^0-9])')


ถ้า [[ $lines < 3 ]] && (( $ports != 80||443 )); แล้ว
    echo "ฉันต้องการลบสิ่งนี้"
อื่น
    echo "ฉันจะไม่ลบสิ่งนี้..."
ไฟ

ฉันได้ลอง (( เพราะฉันอ่านว่ามันจะดีกว่าที่จะใช้กับฟังก์ชันเลขคณิต -- ซึ่งเป็นสิ่งที่ฉันคิดว่าฉันต้องการ แต่ฉันไม่เข้าใจ bash กับอาร์กิวเมนต์แบบมีเงื่อนไขเมื่อมันควรจะเป็นดังนี้: "สิ่งนี้ และ นั่น หรือ นั่น".

หวังว่านี่สมเหตุสมผล ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชมอย่างมาก!

Score:9
ธง cn
ตรวจสอบไฟล์ () {
    อึดอัด '
        เริ่ม {
            เอฟเอส = ":"
            สถานะ = 1
            พอร์ต [80] = 1
            พอร์ต [443] = 1
        }
        NR == 3 || !($2 ในพอร์ต) {สถานะ = 0; ทางออก}
        สิ้นสุด {สถานะการออก}
    ' "1 ดอลลาร์"
}

ไฟล์=portscan.txt
ไฟล์ตรวจสอบ "$file" || echo rm -- "ไฟล์ $"

คำสั่ง awk นั้นจะออกด้วยสถานะ 0 หากไฟล์มีบรรทัดที่ 3 หรือหากเห็นพอร์ต "ไม่เป็นมาตรฐาน"

หากฟังก์ชันส่งคืนค่าที่ไม่ใช่ศูนย์ (ไฟล์มี <= 2 บรรทัดและพอร์ต "มาตรฐาน" เท่านั้น) คำสั่ง rm จะถูกพิมพ์

ลบ เสียงสะท้อน หากผลลัพธ์ออกมาถูกต้อง


อีกทางหนึ่ง:

ตรวจสอบไฟล์ () {
    # ถ้าเกิน 2 บรรทัดให้เก็บไฟล์ไว้
    (( $(wc -l < ​​"$1") > 2 )) && กลับ 0

    # หากมีพอร์ต "ที่ไม่ได้มาตรฐาน" ให้เก็บไฟล์ไว้
    grep -qv -e ':80$' -e ':443$' "$1" && ส่งคืน 0

    #ลบไฟล์
    กลับ 1
}

หรือมากกว่านั้น

ตรวจสอบไฟล์ () {
    (( $(wc -l < ​​"$1") > 2 )) || grep -qv -e ':80$' -e ':443$' "$1"
}
Justin Washek avatar
ma flag
ยอดเยี่ยม นี่เป็นเคล็ดลับ ขอบคุณมาก!
Score:3
ธง ph

ตกลงลองนี้

[~/my_learning/lint]$ cat file.txt
somedomain.com:80
somedomain.com:443
[~/my_learning/lint]$ cat file_dont_delete.txt
somedomain.com:8443
somedomain.com:443

[~/my_learning/lint]$ สำหรับไฟล์ใน file.txt file_dont_delete.txt
ทำ
num_of_lines=$(wc -l $file| xargs | awk '{print $1}')
port_scan=$(awk -F':' '{ if (($2 == "443") || ($2 == "80")) print "matched" }' $file | wc -l | xargs)
ถ้า [ $num_of_lines -le 2 ] && [ $num_of_lines -eq $port_scan ] ; แล้ว
echo "ลบไฟล์ $ ได้"
อื่น
echo "ลบ $file ไม่ได้"
ไฟ
เสร็จแล้ว

#เอาท์พุต
file.txt สามารถลบได้
ไม่สามารถลบ file_dont_delete.txt ได้

ฉันทำตามเงื่อนไขด้านล่าง

  • จำนวนบรรทัด 2 หรือน้อยกว่าหรือ 2
  • และสำหรับแต่ละบรรทัด ฉันใช้ awk เพื่อแยกฟิลด์ 2 ซึ่งเป็นพอร์ต และตรวจสอบว่าเป็น 80 หรือ 443 หรือไม่ และฉันจะพิมพ์ที่ใด การจับคู่.
  • จากนั้นฉันจะนับจำนวนการจับคู่ที่เกิดขึ้น
  • ตามคำอธิบายของคุณ แม้แต่พอร์ตเดียวที่ไม่ได้มาจาก 80 หรือ 443 ก็ปรากฏขึ้น ดังนั้นฉันไม่ควรลบไฟล์

ขอบคุณที่ให้โอกาสฉันในการเขียนโค้ดเชลล์

Score:1
ธง cn

โซลูชันขึ้นอยู่กับ mapfile:

#!/bin/bash

shopt -s extglob

mapfile -tn3 a < $1
[[ ${#a[@]} -lt 3 ]] && { \
[[ ${#a[@]} -gt 0 && ${a[@]/%:@(80|443)} =~ :[0-9]+ ]] || echo rm -v -- $1; }
Score:1
ธง cn

โซลูชันทุบตีบริสุทธิ์ รวมอยู่ในฟังก์ชันและอ่านง่าย:

#!/bin/bash

อาจลบไฟล์ () {
    จำนวนท้องถิ่น = 0
    พอร์ต rLine ภายในเครื่อง
    local otherPort=false
    ในขณะที่ IFS= อ่าน -r -d'' rLine; ทำ
        port="${rLine#*:}"
        ((จำนวน++))
        ถ้า [ "$port" != 80 ] && [ "$port" != 443 ]; แล้ว
            otherPort=จริง
        ไฟ
    เสร็จแล้ว < "$1"
    ถ้า [ $count -le 2 ] && ! $otherPort; แล้ว
        echo "กำลังลบไฟล์ $1"
        rm -- "$1"
    ไฟ
}

อาจลบไฟล์ "$1"
minnmass avatar
in flag
ฉันอาจขาดอะไรไป ฉันไม่เห็นว่าสิ่งนี้จัดการกับกฎ "2 หรือน้อยกว่า" ได้อย่างไร - หากมี 3 บรรทัดที่ทั้งหมดมีพอร์ต 80 `count` จะไม่เพิ่มขึ้น ดังนั้นไฟล์จะไม่ถูกลบ .
rexkogitans avatar
cn flag
@minnmass ขอบคุณ ฉันไม่เข้าใจคำถามที่ถูกต้อง ฉันซ่อมมัน.
Score:-3
ธง in

ในการเปรียบเทียบตัวเลขใน bash คุณต้องใช้ -gt, -ลเป็นต้น < สัญลักษณ์สำหรับการเปลี่ยนเส้นทาง stdin

คุณสามารถใส่การเปรียบเทียบหมายเลขบรรทัดใน (( )) เช่นเดียวกับที่คุณทำกับพอร์ต หรือใช้ -ล ดู https://tldp.org/LDP/abs/html/comparison-ops.html

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา