0

I've been trying to count all files with a specific prefix and then if the number of files with the prefix does not match the number 5 I want to print the prefix.

To achieve this, I wrote the following bash script:

#!/bin/bash
for filename in $(ls); do
    name=$(echo $filename | cut -f 1 -d '.')
    num=$(ls $name* | wc -l)
    if [$num != 5]; then
        echo $name
    fi
done

But I get this error (repeatedly):

./check_uneven_number.sh: line 5: [1: command not found

Thank you!

uller
  • 115
  • 2
  • 10
  • Where you have `$(ls)` you should simply have `*` - this isn't merely more elegant, faster, and simpler, but objectively more correct. http://mywiki.wooledge.org/ParsingLs – tripleee Feb 18 '16 at 16:36
  • Possible duplicate of [How do I compare two string variables in an 'if' statement in Bash?](http://stackoverflow.com/questions/4277665/how-do-i-compare-two-string-variables-in-an-if-statement-in-bash) – Benjamin W. Feb 18 '16 at 16:49

2 Answers2

1

The if statement takes a command, runs it, and checks its exit status. Left bracket ([) by itself is a command, but you wrote [$num. The shell expands $num to 1, creating the word [1, which is not a command.

if [ $num != 5 ]; then
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
0

Your code loops over file names, not prefixes; so if there are three file names with a particular prefix, you will get three warnings, instead of one.

Try this instead:

# Avoid pesky ls
printf '%s\n' * |
# Trim to just prefixes
cut -d . -f 1 |
# Reduce to unique
sort -u |
while IFS='' read -r prefix; do
    # Pay attention to quoting
    num=$(printf . "$prefix"* | wc -c)
    # Pay attention to spaces
    if [ "$num" -ne 5 ]; then
        printf '%s\n' "$prefix"
    fi
done

Personally, I'd prefer case over the clunky if here, but it takes some getting used to.

tripleee
  • 175,061
  • 34
  • 275
  • 318