Tom
Tom

Reputation: 67

issue with if statement in bash

I have issue with an if statement. In WEDI_RC is saved log file in the following format:

name_of_file date number_of_starts

I want to compare first argument $1 with first column and if it is true than increment number of starts. When I start my script it works but just with one file, eg:

file1.c 11:23:07 1                  
file1.c 11:23:14 2  
file1.c 11:23:17 3  
file1.c 11:23:22 4  
file2.c 11:23:28 1  
file2.c 11:23:35 2  
file2.c 11:24:10 3  
file2.c 11:24:40 4  
file2.c 11:24:53 5  
file1.c 11:25:13 1  
file1.c 11:25:49 2  
file2.c 11:26:01 1  
file2.c 11:28:12 2

Every time when I change file it begin counts from 1. I need to continue with counting when it ends.

Hope you understand me.

while read -r line      
do
    echo "line:"
    echo $line
    if [ "$1"="$($line | grep ^$1)" ]; then
        number=$(echo $line | grep $1 | awk -F'[ ]' '{print $3}')
    else 
        echo "error"
    fi
done < $WEDI_RC

echo "file"
((number++))
echo $1 `date +"%T"` $number >> $WEDI_RC

Upvotes: 0

Views: 106

Answers (2)

Jonathan Leffler
Jonathan Leffler

Reputation: 754920

There are at least two ways to resolve the problem. The most succinct is probably:

echo "$1 $(date +"%T") $(($(grep -c "^$1 " "$WEDI_RC") + 1))" >> "$WEDI_RC"

However, if you want to have counts for each file separately, you can do that using an associative array, assuming you have Bash version 4.x (not 3.x as is provided on Mac OS X, for example). This code assumes the file is correctly formatted (so that the counts do not reset to 1 each time the file name changes).

declare -A files                       # Associative array
while read -r file time count          # Split line into three variables    
do
    echo "line: $file $time $count"    # One echo - not two
    files[$file]="$count"              # Record the current maximum for file
done < "$WEDI_RC"

echo "$1 $(date +"%T") $(( ${files[$1]} + 1 ))" >> "$WEDI_RC"

The code uses read to split the line into three separate variables. It echoes what it read and records the current count. When the loop's done, it echoes the data to append to the file. If the file is new (not mentioned in the file yet), then you will get a 1 added.

If you need to deal with the broken file as input, then you can amend the code to count the number of entries for a file, instead of trusting the count value. The bare-array reference notation used in the (( … )) operation is necessary when incrementing the variable; you can't use ${array[sub]}++ with the increment (or decrement) operator because that evaluates to the value of the array element, not its name!

declare -A files                       # Associative array
while read -r file time count          # Split line into three variables    
do
    echo "line: $file $time $count"    # One echo - not two
    ((files[$file]++))                 # Count the occurrences of file
done < "$WEDI_RC"

echo "$1 $(date +"%T") $(( ${files[$1]} + 1 ))" >> "$WEDI_RC"

You can even detect whether the format is in the broken or fixed style:

declare -A files                       # Associative array
while read -r file time count          # Split line into three variables    
do
    echo "line: $file $time $count"    # One echo - not two
    if [ $((files[$file]++)) != "$count" ]
    then echo "$0: warning - count out of sync: ${files[$file]} vs $count" >&2
    fi
done < "$WEDI_RC"

echo "$1 $(date +"%T") $(( ${files[$1]} + 1 ))" >> "$WEDI_RC"

Upvotes: 1

AdrieanKhisbe
AdrieanKhisbe

Reputation: 4058

I don't get exactly what you want to achieve with your test [ "$1"="$($line | grep ^$1)" ] but it seems you are checking that the line start with the first argument.

If it is so, I think you can either:

  • provide the -o option to grep so that it print just the matched output (so $1)
  • use [[ "$line" =~ ^"$1" ]] as test.

Upvotes: 1

Related Questions