Puncte:14

Ștergeți un fișier dacă sunt îndeplinite mai multe condiții

drapel ma

Ceea ce am nevoie

Am un script existent care extrage informații despre porturi pentru domenii și le stochează într-un fișier text numit portscan.txt. Exemplu:

portscan.txt fişier:

somedomain.com:80
somedomain.com:443

Doresc să șterg informațiile numai dacă sunt îndeplinite anumite condiții. Aceste condiții includ:

  • Fișierul cu domeniile ar trebui să aibă 2 sau mai puține linii
  • Porturile ar trebui să fie doar 80 sau 443 (adică, nu vreau să șterg fișierul dacă 8080, 8443 sau orice alt port există în fișier).

Notă: Deci, practic, fișierul exemplu furnizat mai sus ar trebui să să fie șters, dar nu vreau să șterg fișierul dacă există 2 linii, dar porturile sunt 8080 sau 8443 (sau orice alt port de altfel) Exemplu de genul:

somedomain.com:8443
somedomain.com:443

Asta ar trebui nu fi sters.

Ce am încercat

Am încercat să scriu asta și iată ce am:

#!/bin/bash

linii=$(cat portscan.txt | wc -l)
porturi=$(cat portscan.txt | grep -Pv '(^|[^0-9])(80|443)($|[^0-9])')


dacă [[ $linii < 3 ]] && [[ $porturi != 80 ]]; atunci
    dacă [[ $porturi != 443 ]]; atunci
        echo „Trebuie să șterg asta”
    fi
altfel
    echo "NU voi șterge asta..."
fi

Aceasta este a doua redare a scriptului, am încercat imbricat dacă declarații pentru că nu am putut face o condiție ca aceasta:

DACĂ portscan.txt are mai puțin de două linii ȘI porturile sunt NU 80 SAU 443

De asemenea, am încercat acest lucru într-un mod mult mai simplu, astfel:

#!/bin/bash

linii=$(cat portscan.txt | wc -l)
porturi=$(cat portscan.txt | grep -Pv '(^|[^0-9])(80|443)($|[^0-9])')


dacă [[ $linii < 3 ]] && (( $porturi != 80||443 )); atunci
    echo „Trebuie să șterg asta”
altfel
    echo "NU voi șterge asta..."
fi

Am încercat (( pentru că am citit că acest lucru este mai bine să fie folosit cu funcții aritmetice - care este ceea ce credeam că am nevoie, dar nu sunt la fel de priceput cu argumente condiționate atunci când ar trebui să fie de genul: „Acesta și acea sau acea".

Sperăm că acest lucru are sens, orice ajutor ar fi foarte apreciat!

Puncte:9
drapel cn
fișier de verificare() {
    awk'
        ÎNCEPE {
            FS = ":"
            stare = 1
            porturi[80] = 1
            porturi[443] = 1
        }
        NR == 3 || !($2 în porturi) {starea = 0; Ieșire}
        END {starea de ieșire}
    "$1"
}

fișier=portscan.txt
fișier de verificare „$fișier” || echo rm -- "$fișier"

Acea comandă awk va ieși cu starea 0 dacă fișierul are o a treia linie sau dacă vede un port „non-standard”.

Dacă funcția returnează diferit de zero (fișierul are <= 2 linii și doar porturi „standard”), atunci comanda rm este tipărită.

Elimina ecou dacă rezultatele arată corect.


Alternativ:

fișier de verificare() {
    # dacă are mai mult de 2 rânduri, păstrați fișierul
    (( $(wc -l < ​​"$1") > 2 )) && returnează 0

    # dacă există un port „non-standard”, păstrați fișierul
    grep -qv -e ':80$' -e ':443$' "$1" && returnează 0

    # șterge fișierul
    întoarce 1
}

sau, mai concis

fișier de verificare() {
    (( $(wc -l < ​​"$1") > 2 )) || grep -qv -e ':80$' -e ':443$' "$1"
}
Justin Washek avatar
drapel ma
Minunat, asta a reușit, mulțumesc mult!
Puncte:3
drapel ph

Ok, încearcă asta

[~/my_learning/lint]$ fișier pisică.txt
somedomain.com:80
somedomain.com:443
[~/my_learning/lint]$ cat file_dont_delete.txt
somedomain.com:8443
somedomain.com:443

[~/my_learning/lint]$ pentru fișierul din file.txt file_dont_delete.txt
do
num_of_lines=$(wc -l $fișier| xargs | awk '{print $1}')
port_scan=$(awk -F':' '{ dacă (($2 == "443") || ($2 == "80")) printează "potrivit" }' $fișier | wc -l | xargs)
if [ $numar_linii -le 2 ] && [ $numar_linii -eq $port_scan ] ; atunci
echo „$fișierul poate fi șters”
altfel
echo „$fișierul nu poate fi șters”
fi
Terminat

# Ieșire
file.txt poate fi șters
file_dont_delete.txt nu poate fi șters

Urmăresc condițiile de mai jos

  • numărul de linii 2 sau mai mic decât sau 2.
  • și pentru fiecare linie, am folosit awk pentru a extrage câmpul 2 care este un port și a verifica dacă este fie 80, fie 443, iar pe oricare, imprimez potrivire.
  • Apoi număr câte potriviri au avut loc.
  • Conform descrierii dvs., chiar și un singur port care nu este de la 80 sau 443 este prezentat, atunci nu ar trebui să șterg fișierul.

Vă mulțumesc că mi-ați oferit această oportunitate de a scrie codul shell.

Puncte:1
drapel cn

Soluție bazată pe 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; }
Puncte:1
drapel cn

Soluție pură de bash, ambalată într-o funcție și ușor de citit:

#!/bin/bash

possiblyDeleteFile() {
    număr local=0
    portul local rLine
    local otherPort=fals
    in timp ce IFS= citeste -r -d'' rLine; do
        port="${rLine#*:}"
        ((numărare++))
        if [ "$port" != 80 ] && [ "$port" != 443 ]; atunci
            otherPort=true
        fi
    gata < "$1"
    dacă [ $count -le 2 ] && ! $altulPort; atunci
        echo „Ștergerea fișierului $1”
        rm -- „$1”
    fi
}

eventual șterge fișierul „$1”
minnmass avatar
drapel in
Poate că îmi lipsește ceva, nu văd cum se descurcă aceasta regula „2 sau mai puțin” - dacă există 3 linii care au toate portul 80, `count` nu va fi incrementat, deci fișierul nu va fi șters .
rexkogitans avatar
drapel cn
@minnmass Mulțumesc, nu am înțeles corect întrebarea. L-am reparat.
Puncte:-3
drapel in

Pentru a face comparații numerice în bash, trebuie să utilizați -gt, -lt, etc < simbolul este pentru redirecționarea stdin.

Puteți fie include comparația numărului de rând în (( )), așa cum ați făcut-o pentru port, sau puteți utiliza -lt Vedea https://tldp.org/LDP/abs/html/comparison-ops.html

drapel hr
`

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.