0

This might be a naive question, but I am new to bash scripting. I am trying to open a file and count the number of lines in that file and if it is greater than 4, then output something. I have figured out how to pass and save the line count to a variable, but I cannot access the file in the bash when I do not pass it the exact name. Therefore, I have this program called new_test written as so:

test_function()
{
    file_name='test_text.txt'
    n=$(wc -l < $file_name)
    if [ 'n > 2' ]
    then
        echo "Too many lines"
    fi
}
test_function

This program works, but when I try and make it more generic to accept any file by changing line 3 from:

file_name='test_text.txt'

to

file_name=$1

And then call

./new_test test_text.txt

it outputs:

./test_file[4]: : cannot open

From my understanding, the $1 is the second argument passed, and in the case of ./new_test test_text.txt, this would be the test_text.txt file. Do I need to obtain the address of the second argument or is the notation different in order to do this? Thank you in advance.

1 Answers1

0

The $1 inside of the function is the function argument, not the script argument. You need to take that top level argument and pass it back into the function itself.

test_function()
{
    file_name="$1"
    n=$(wc -l < $file_name)
    if [ 'n > 2' ]
    then
        echo "Too many lines"
    fi
}
test_function "$1"

Make sure you don't forget the quotes either, or you'll run into problems with files that have spaces in their path.

Robert Hafner
  • 3,364
  • 18
  • 23
  • @ Robert Hafner Huh, that is interesting, so I have to pass the $1 in the function call. Does this mean if I have multiple parameters, I have to pass each one individually? Or is there a simple notation to pass them all? – learningtoprogram123 Jan 20 '22 at 19:20
  • 2
    `if [ 'n > 2' ]` simply checks whether the static string `n > 2` is non-empty, which of course it is. – tripleee Jan 20 '22 at 19:25
  • 2
    @learningtoprogram123 Use `"$@"` (including the double-quotes) to pass on all arguments. See [this question](https://stackoverflow.com/questions/3811345/how-to-pass-all-arguments-passed-to-my-bash-script-to-a-function-of-mine). – Gordon Davisson Jan 20 '22 at 19:26
  • @tripleee Would the correct way of checking if the value stored in n is greater than 2 be: if [ 'n' > 2 ] – learningtoprogram123 Jan 20 '22 at 19:28
  • 1
    Try `if ((n > 2))` but I would perhaps avoid reading a file of unknown size with `wc -l` just to see how many lines there are; I would probably write this in Awk instead, which lets me quit early. – tripleee Jan 20 '22 at 19:31
  • @tripleee Thank you I just tried it and it worked! I just do not understand why when checking comparison I have to use (()) instead of [ ] in the if statement. But thank you nonetheless. – learningtoprogram123 Jan 20 '22 at 19:36
  • 2
    Indeed, the notations are somewhat bewildering; perhaps see https://stackoverflow.com/questions/2188199/how-to-use-double-or-single-brackets-parentheses-curly-braces – tripleee Jan 20 '22 at 19:42
  • 1
    The double quotes mark it as an arthematic expression. You could also use the bracket tests with the -ge (greater than or equal to) test. For that it really comes down to personal preference. – Robert Hafner Jan 20 '22 at 19:42
  • You mean double parentheses, and "arithmetic". – tripleee Jan 20 '22 at 19:44
  • @learningtoprogram123 You could use `((n > 2))`, `[[ $n -gt 2 ]]`, or `[ "$n" -gt 2 ]` (or a number of variants on each of those). The short summary is that `(( ))` does arithmetic, while `[ ]` and `[[ ]]` primarily do string comparisons (and `[ ]` is a command, so its syntax is weird because e.g. `>` and `<` are I/O redirections unless they're quoted/escaped). See [this unix & linux answer](https://unix.stackexchange.com/questions/306111/what-is-the-difference-between-the-bash-operators-vs-vs-vs/306141#306141) for more info about different bracket/brace/parenthesis expressions. – Gordon Davisson Jan 20 '22 at 21:16