How can I get my bash script to work?

My bash script doesn't work the way I want:

#!/bin/bash

total="0"
count="0"
#FILE="$1" This is the easier way
for FILE in $*
do
    # Start processing all processable files
    while read line
    do
        if [[ "$line" =~ ^Total ]];
        then
            tmp=$(echo $line | cut -d':' -f2)
            count=$(expr $count + 1)
            total=$(expr $total + $tmp)
        fi     
    done < $FILE
done
echo "The Total Is: $total"
echo "$FILE"

      

Is there any other way to change this script so that it reads the arguments in $1

instead $FILE

? I've tried using a loop while

:

while [ $1 != "" ]
  do ....
done

      

Also when I implement that the code is repeated. Is there a way to fix this?

Another problem I am facing is that when I have multiple files hi*.txt

it gives me duplicates. What for? I have files of type hi1.txt

hi1.txt~

, but the tilde file is 0 bytes, so my script shouldn't find anything.


I'm fine, but I can improve. I appreciate your awk suggestions, but is currently beyond my level as a unix programmer.

Strager: The files that my text editor generates don't automatically contain anything ... that's 0 bytes. But I went and deleted them to be sure. But my script actually reads everything twice. I guess his looping again when he really shouldn't. I tried to disable this action using exit commands. But it was not successful.

while [ "$1" != "" ]; do
    # Code here

    # Next argument
    shift
done

      

This code is pretty cute, but I am giving all the possible commands in one go. Example: hello [145] .txt If this were done, all three files would be read at once. Suppose the user enters hi * .txt; Then I get all my hello files twice and then added again.

How can I code it so that it reads my files (only once) after the hi * .txt spec? I really think this is due to the lack of $ 1.

-1


source to share


3 answers


It looks like you are trying to compose totals from the lines labeled "Total:" in the provided files. It is always helpful to indicate what you are trying to do as well as how you are trying to do it (see How to Ask Smart Way Questions ).

If so, then you are making it as difficult as I see it. What happened with:

grep '^Total:' "$@" |
cut -d: -f2 |
awk '{sum += $1}
     END { print sum }'

      

This does not print "Total is" etc .; and it is not clear why you echo $ FILE at the end of your version.

awk

You can use Perl or any other suitable program instead ; you could do all the work in Perl or Python - indeed, work cut

can be done with awk

:

grep "^Total:" "$@" |
awk -F: '{sum += $2}
         END { print sum }'

      

Taking even more, all the work can be done with awk

:



awk -F: '$1 ~ /^Total/ { sum += $2 }
         END { print sum }' "$@"

      

The code in Perl won't be much more complicated and the result could be faster:

perl -na -F: -e '$sum += $F[1] if m/^Total:/; END { print $sum; }' "$@"

      

When repeating filename arguments provided in a shell script, instead of ' $*

should be used "$@"

', as the latter notation does not preserve spaces in filenames.

Your comment about ` $1

` confuses me. You can ask to read from a file whose name is in $1

at each iteration; this is done with:

while [ $# -gt 0 ]
do
     ...process $1...
     shift
done

      

NTN!

+2


source


If you define a function, it will receive an argument as $ 1. Why is $ 1 more valuable to you than $ FILE, though?



#!/bin/sh

process() {
    echo "doing something with $1"
}

for i in "$@" # Note use of "$@" to not break on filenames with whitespace
do
    process "$i"
done

      

+1


source


while [ "$1" != "" ]; do
    # Code here

    # Next argument
    shift
done

      

In your problem with tilde files ... these are temporary files created by your text editor. Remove them if you don't want them to match your glob (wildcard) expression. Otherwise, filter them out in your script (not recommended).

+1


source







All Articles