-2

I am not sure what s wrong with my below script even I removed whitespaces but I am still getting below error "[: too many arguments"

oldPlugin="/old/plugins/"
cd "$oldPlugin" || true
for FILE in *; do
  if [ "$FILE" == "csharp-plugin"* ] || [ "$FILE" == "flex-plugin"* ] || [ "$FILE" == "go-plugin"* ] || [ "$FILE" == "html-plugin"* ] || [ "$FILE" == "iac-plugin"* ] || [ "$FILE" == "jacoco-plugin"* ] || [ "$FILE" == "java-plugin"* ] || [ "$FILE" == "javascript-plugin"* ] || [ "$FILE" == "kotlin-plugin"* ] || [ "$FILE" == "php-plugin"* ] || [ "$FILE" == "python-plugin"* ] || [ "$FILE" == "ruby-plugin"* ] || [ "$FILE" == "scala-plugin"* ] || [ "$FILE" == "vbnet-plugin"* ] || [ "$FILE" == "xml-plugin"* ]; then
    rm -rf "$extensionPlugin"/"$FILE"
 fi
done

if I do rm -rf with specified files it removes, but when I add if condition it gives me error, also if I keep let say 5 or 6 file names in if condition it works but if I keep more than that it gives me error,

Do I need to short if condition or need to have another condition, Please help

Regards

Samurai
  • 55
  • can you elaborate from you previous delete question and it's dupplicate : https://unix.stackexchange.com/questions/711454/too-many-arguments-if-statement ? (in short * would expand to all matching file and break test syntax). – Archemar Aug 01 '22 at 07:34
  • @Archemar Yes if I do rm -rf with specified files it removes, but when I add if condition it gives me error, also if I keep let say 5 or 6 file names in if condition it works but if I keep more than that it gives me error, to avoid confusion I deleted my previous post, sorry for that since suggestion I tried not working and I was leading same issue
    • is to cover all the filename which has number wildcards

    can you please help

    – Samurai Aug 01 '22 at 07:47
  • re-asking/refining a question if fine. Can you edit your question with those details, comment are hard to read. – Archemar Aug 01 '22 at 08:50
  • One of your lines is far too long to be easily read. I strongly recommend you start adding line-feeds (and appropriate indentation) to make your scripts more readable. You can add a line-feed almost anywhere in a line of shell code line by preceding it with a backslash \ (but beware of quotes). You can also add linefeeds after a || or && – cas Aug 01 '22 at 12:26
  • It's not about adding conditions, it's not about long lines, it's about the fact that [[ "$var" == foo* ]] is different from [ "$var" == foo* ]. The former does pattern matching of the contents of $var against foo*. The latter does filename generation globbing of foo* and then an equality test if that results in only one word, and an error if it results in more than one word (from more than one matching file). – ilkkachu Aug 01 '22 at 12:46
  • The question I marked your first post as a duplicate of seems to describe that adequately. But if it didn't, I wonder why you'd just post the same question again, without regard to the information you had already been given? If that linked question doesn't explain it well enough, you might do well to say that and ask for further clarification explicitly, describing the parts you don't understand. – ilkkachu Aug 01 '22 at 12:47
  • @ilkkachu , I apologize for that but somehow I was not able to edit or comment so i removed and asked same question, it may sound like stupid but it was the situation, and I sincerely sorry for that, wont happen again. – Samurai Aug 01 '22 at 12:50

1 Answers1

5

There's the [[ var = pattern ]] or [[ var == pattern ]] operator of the Korn shell (also supported by a few other shells these days, but not part of the standard sh syntax), and there's the [ command that supports the = operator for string equality comparison.

Some [ implementations support a == operator as well but that's just as an alias to = for string equality, not pattern matching. Some [ implementations like the [ builtin of yash or zsh support a =~ operator for regexp matching, but again, that's not available in standard sh + utilities syntax.

[ being just a ordinary command,

[ "$FILE" == "csharp-plugin"* ]

Is interpreted the same as:

echo "$FILE" == "csharp-plugin"* ]

Or any simple command, and "csharp-plugin"* is expanded by the shell to the list of file names in the current directory that start with csharp-plugin via a mechanism called globbing or filename generation or pathname expansion and pass them as separate arguments to [.

So if the current directory contained csharp-plugin1 and csharp-plugin2, [ would be called with [, csharp-plugin1, ==, csharp-plugin1, csharp-plugin2 and ] as arguments, and complain about that extra csharp-plugin2 argument which it can't make sense of.

Pattern matching in sh is done with the case construct.

oldPlugin="/old/plugins/"
cd -- "$oldPlugin" || exit
for FILE in *; do
  case "$FILE" in
    (csharp-plugin* | flex-plugin* | go-plugin* |...)
      rm -rf -- "$extensionPlugin"/"$FILE";;
  esac
done

If you wanted to use a if, construct, you could define a helper function such as:

match()
  case $1 in
    ($2) true;;
    (*) false;;
  esac

And use it as:

if match "$FILE" 'csharp-plugin*' || match...; then
  ...
fi

In the Korn shell, or with the bash shell and after shopt -s extglob (not needed in recent versions of bash) or with zsh and after set -o kshglob), you could also do:

if [[ $FILE = @(csharp|flex|go|...)-plugin* ]]; then...

In zsh, without kshglob, alternation is done simply with:

if [[ $FILE = (csharp|flex|go|...)-plugin* ]]; then...

In sh, you could simplify a bit with:

oldPlugin="/old/plugins/"
cd -- "$oldPlugin" || exit
for FILE in *-plugin*; do
  case "${FILE%%-plugin*}" in
    (csharp | flex | go |...)
      rm -rf -- "$extensionPlugin"/"$FILE";;
  esac
done
  • Thank you Stéphane Chazelas, thank you for this explanation I have understood the issue, will check my approach and correct it – Samurai Aug 01 '22 at 10:00