Điểm:14

Xóa tệp nếu đáp ứng nhiều điều kiện

lá cờ ma

Tôi cân gi

Tôi có một tập lệnh hiện có để lấy thông tin cổng cho các miền và lưu trữ nó vào một tệp văn bản có tên portcan.txt. Ví dụ:

portcan.txt tập tin:

somedomain.com:80
somedomain.com:443

Tôi chỉ muốn xóa thông tin nếu một số điều kiện được đáp ứng. Những điều kiện này bao gồm:

  • Tệp có tên miền phải có 2 dòng trở xuống
  • Các cổng chỉ nên là 80 hoặc 443 (nghĩa là tôi không muốn xóa tệp nếu 8080, 8443 hoặc bất kỳ cổng nào khác tồn tại trong tệp).

Ghi chú: Về cơ bản, tệp ví dụ được cung cấp ở trên Nên bị xóa, nhưng tôi không muốn xóa tệp nếu có 2 dòng, nhưng các cổng là 8080 hoặc 8443 (hoặc bất kỳ cổng nào khác cho vấn đề đó) Ví dụ như vậy:

somedomain.com:8443
somedomain.com:443

Cái này nên không phải bị xóa.

Những gì tôi đã cố gắng

Tôi đã thử viết kịch bản này ra và đây là những gì tôi có:

#!/bin/bash

lines=$(cat portcan.txt | wc -l)
cổng=$(cat portcan.txt | grep -Pv '(^|[^0-9])(80|443)($|[^0-9])')


if [[ $lines < 3 ]] && [[ $ports != 80 ]]; sau đó
    nếu [[ $port != 443 ]]; sau đó
        echo "Tôi cần xóa cái này"
    fi
khác
    echo "Tôi sẽ KHÔNG xóa cái này..."
fi

Đây là lần hiển thị thứ hai của tập lệnh, tôi đã thử lồng vào nhau nếu tuyên bố vì tôi không thể thực hiện một điều kiện như thế này:

NẾU portcan.txt nhỏ hơn hai dòng các cổng là KHÔNG PHẢI 80 HOẶC 443

Tôi cũng đã thử điều này theo cách đơn giản hơn nhiều như sau:

#!/bin/bash

lines=$(cat portcan.txt | wc -l)
cổng=$(cat portcan.txt | grep -Pv '(^|[^0-9])(80|443)($|[^0-9])')


if [[ $lines < 3 ]] && (( $ports != 80||443 )); sau đó
    echo "Tôi cần xóa cái này"
khác
    echo "Tôi sẽ KHÔNG xóa cái này..."
fi

tôi đã thử (( bởi vì tôi đọc được rằng điều này tốt hơn nên được sử dụng với các hàm số học -- đó là điều tôi nghĩ là tôi cần, nhưng tôi không rành lắm với các đối số điều kiện khi nó phải như sau: "Cái này điều đó hoặc điều đó".

Hy vọng rằng điều này có ý nghĩa, bất kỳ trợ giúp sẽ được đánh giá rất cao!

Điểm:9
lá cờ cn
tệp kiểm tra () {
    awk'
        BẮT ĐẦU {
            FS = ":"
            trạng thái = 1
            cổng [80] = 1
            cổng [443] = 1
        }
        NR == 3 || !($2 trong cổng) {status = 0; lối ra}
        KẾT THÚC {trạng thái thoát}
    ' "$1"
}

tệp = portscan.txt
tệp kiểm tra "$ tệp" || tiếng vang rm -- "$file"

Lệnh awk đó sẽ thoát với trạng thái 0 nếu tệp có dòng thứ 3 hoặc nếu tệp thấy cổng "không chuẩn".

Nếu hàm trả về giá trị khác 0 (tệp có <= 2 dòng và chỉ có các cổng "tiêu chuẩn"), thì lệnh rm sẽ được in.

Gỡ bỏ tiếng vang nếu kết quả nhìn đúng.


luân phiên:

tệp kiểm tra () {
    # nếu nhiều hơn 2 dòng, hãy giữ nguyên tệp
    (( $(wc -l < ​​"$1") > 2 )) && trả về 0

    # nếu tồn tại một cổng "không chuẩn", hãy giữ lại tệp
    grep -qv -e ':80$' -e ':443$' "$1" && return 0

    # xóa tập tin
    trả lại 1
}

hoặc, ngắn gọn hơn

tệp kiểm tra () {
    (( $(wc -l < ​​"$1") > 2 )) || grep -qv -e ':80$' -e ':443$' "$1"
}
Justin Washek avatar
lá cờ ma
Tuyệt vời, điều này đã làm được điều đó, cảm ơn bạn rất nhiều!
Điểm:3
lá cờ ph

Được rồi, hãy thử cái này

[~/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]$ cho tệp trong file.txt file_dont_delete.txt
làm
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)
nếu [ $num_of_lines -le 2 ] && [ $num_of_lines -eq $port_scan ] ; sau đó
tiếng vang "$file có thể bị xóa"
khác
echo "Không thể xóa tệp $"
fi
xong

# Đầu ra
file.txt có thể bị xóa
không thể xóa file_dont_delete.txt

Tôi làm theo các điều kiện dưới đây

  • số dòng 2 hoặc nhỏ hơn hoặc 2.
  • và đối với mỗi dòng, tôi đã sử dụng awk để trích xuất trường 2 là cổng và kiểm tra xem đó là 80 hay 443 và trên bất kỳ dòng nào, tôi đang in phù hợp.
  • Sau đó, tôi đang đếm có bao nhiêu trận đấu xảy ra.
  • Theo mô tả của bạn, ngay cả một cổng duy nhất không phải từ 80 hoặc 443 được hiển thị, thì tôi không nên xóa tệp.

Cảm ơn bạn đã cho tôi cơ hội viết mã shell này.

Điểm:1
lá cờ cn

Giải pháp bash thuần túy, được bao bọc trong một chức năng và dễ đọc:

#!/bin/bash

có thểDeleteFile() {
    số cục bộ = 0
    cổng rLine cục bộ
    cục bộ otherPort=false
    trong khi IFS= read -r -d'' rLine; làm
        cổng="${rLine#*:}"
        ((đếm ++))
        if [ "$port" != 80 ] && [ "$port" != 443 ]; sau đó
            otherPort=true
        fi
    xong < "$1"
    nếu [ $count -le 2 ] && ! $ otherPort; sau đó
        echo "Đang xóa tệp $1"
        rm -- "$1"
    fi
}

có thểXóaTệp "$1"
minnmass avatar
lá cờ in
Tôi có thể thiếu một cái gì đó, tôi không thấy cách điều này xử lý quy tắc "2 hoặc ít hơn" - nếu có 3 dòng đều có cổng 80, `count` sẽ không được tăng lên, vì vậy tệp sẽ không bị xóa .
rexkogitans avatar
lá cờ cn
@minnmass Cảm ơn bạn, tôi không hiểu đúng câu hỏi. Tôi sửa nó rồi.
Điểm:1
lá cờ cn

Giải pháp dựa trên mapfile:

#!/bin/bash

shopt -s extglob

mapfile -tn3 a < $1
[[ ${#a[@]} -lt 3 ]] && { \
[[ ${#a[@]} -gt 0 && ${a[@]/%:@(80|443)} =~ :[0-9]+ ]] || tiếng vang rm -v -- $1; }
Điểm:-3
lá cờ in

Để thực hiện so sánh số trong bash, bạn cần sử dụng -gt, -lt, v.v. < biểu tượng dành cho chuyển hướng stdin.

Bạn có thể gửi so sánh số dòng trong (( )) giống như bạn đã làm cho cổng hoặc sử dụng -lt Nhìn thấy https://tldp.org/LDP/abs/html/comparison-ops.html

lá cờ hr
`

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.