Simple BASH - how to read file line by line

6,117

I'd recommend starting like this:

#!/bin/bash
file="/home/foo/documents/iptxt"

while read num addr ; do 
    if [[ "$num" && "$addr" ]] ; then 
        echo "$addr has tried to log in $num times" 
    fi
done < "$file"

This way, read stores the first word of each line in $num and the rest of the line in $addr, which should only be the IP address. Then inside the while loop, we check if both are not empty, and if that is the case, print the message.

Share:
6,117
DivZ
Author by

DivZ

Updated on September 18, 2022

Comments

  • DivZ
    DivZ over 1 year

    I have a file that has the following:

    6 192.168.0.4   
    13 192.168.0.2        
    2 192.168.0.9
    

    First number is the number of times the IP on the right has tried to login into my machine (ssh) from within the same network. Goal is to block that IP using netfilter if the attempt is more than 3. Here, 2 of the entries match the criteria. Note: There might be more than 3 entries.

    I can't figure out a way to sort this file line by line (I'm VERY new to BASH). Here is what I tried:

    #!/bin/bash
    file="/home/foo/documents/iptxt"
    while IFS='' read line || [[ -n "$line" ]]; do
      char1=`awk '{ print $1 }' $file`
      char2=`awk '{ print $2 }' $file`
      if $char1 -gt 3
      then
        echo "$char2 has tried to login $char1 times
      fi
    done <$file
    

    This gives a "command not found" error pointing to the 5th line (if statement). No wonder, because I echoed $char1_attempt and it gives:

    6 13 2
    6 13 2
    6 13 2
    

    For the time being, J just want it to print out lines like:

    192.168.0.4 has tried to login 6 times
    192.168.0.2 has tried to login 13 times
    192.168.0.1 has tried to login 2 times
    

    Please help!

    • John1024
      John1024 about 6 years
      Replace if $char1 -gt 3 with if [ "$char1" -gt 3 ]. In general, whenever you have a shell syntax error, a good first step is to cut and paste your code into shellcheck.net and correct the errors (important) and warnings (might be important) that it identifies. If you have trouble understanding its messages, then come here and ask.
  • Pablo Bianchi
    Pablo Bianchi about 6 years
    And you can set internal field separator variable for values separated by commas (IFS=",").
  • dessert
    dessert about 6 years
    What happened to $char1 -gt 3 from the question (Goal is to block that IP using netfilter if the attempt is more than 3.)? Also, adding at least || [[ -n "$num" ]] seems like a good idea to cover the case of the last line not ending in newline.