0

I'm a bash begginer and I want to solve the next problem: Find all the files in a directory received as command line argument that contain numbers greater than 1000. If the command line doesn't contain any arguments, display a message and exit.

Firstly I wanted to check only if there is a number equal to 1000, because I don't know how to check if it's bigger using grep. This is my code:

#!/bin/bash

if [ $0 -eq 0 ]
then
    echo "No arguments"
    exit 0
fi

for filename in $1
do
    if [ -f filename ]
    then
        if grep -q "1000" $filename
            echo $filename
        fi
    fi
done

And it raises some errors on line 3 and 15 andI don't know why.

Can somebody help me,please?

UPDATED CODE:

#!/bin/bash

if [ $1 -eq 0 ]
then
    echo "No arguments"
    exit 0
fi

for filename in $1
do
    if [ -f filename ]
    then
        if grep -q "1000" $filename
        then
            echo $filename
        fi
    fi
done
  • Try shellcheck.net. – Paulo Tomé Mar 26 at 16:52
  • $0 is not an integer, it represents the shell, so it's equal to bash. -eq expects an integer, hence the error. – schrodigerscatcuriosity Mar 26 at 16:55
  • And you are missing a then in your second if. – schrodigerscatcuriosity Mar 26 at 16:57
  • 1
    When asking questions about an error, it is important that you actually include the error! Telling us "it raises some errors" doesn't really give us much information :) Please edit your question and clarify. – terdon Mar 26 at 17:02
  • I've changed but now I have error on line 3:unary operator expected – Gaboru Mar 26 at 17:05
2

$0 expands to the name of the script, not the command line arguments.

3.4.2 Special Parameters

If you want to check if there are no command line arguments you can use:

if (($#==0)); then
    echo "No arguments" >&2
    exit 1
fi

$# will expand to the number of command line arguments. Also note we are redirecting the error to stderr and exiting with a code of 1 rather than 0. 0 typically means success where non-zero means error.

$1 will only ever be a single option so there is no need to loop over it. Also, it seems like your script is only supposed to receive a single directory as an argument, and while this is technically a file it will fail the -f test.

grep -q "1000" $filename will search for the presence of 1000 within the file and won't find any numbers greater than 1000 unless they also literally contain 1000 (ie: 101000).

You could use a recursive grep on the directory to perform a regex search to look for numbers 1000 or greater:

grep -rE '[1-9][0-9]{3,}' "$1"

This will print the filenames and match but if you want to only print the filename you can do:

grep -rEl '[1-9][0-9]{3,}' "$1"
| improve this answer | |
  • 1
    grep -l to print just the filenames? at least with GNU grep – ilkkachu Mar 26 at 17:41
  • @ilkkachu: Thanks, seems that option is available on BSD and solaris grep as well. – jesse_b Mar 26 at 17:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.