What does [co] mean in the "rm -rf filename[co]" command?

[co] isn't a parameter to the rm command - it's a shell glob that matches a pattern equal to a single character from the set [co] - in other words, it matches either a c or an o a the end of the filename. From man bash:

[...]  Matches any one of the enclosed characters

To match both foo.coffee and foo.js, since the suffixes don't contain any common substrings at all, the best you could do is foo.* which would match any filename starting with foo. Instead you could use brace expansion e.g.

rm foo.{coffee,js}

It is not a parameter but a collection of letters (or a "shell glob"). This is the same:

rm -rf /tmp/hello.py[co]

is the same as

rm -rf /tmp/hello.pyc
rm -rf /tmp/hello.pyo

Similar ...

rm -rf /tmp/hello.py[c-o]

would delete anything from /tmp/hello.pyc up to and including /tmp/hello.pyo following ASCII ordering.

rm -rf /tmp/hello.py[ab][cd]

would remove ...

rm -rf /tmp/hello.pyac
rm -rf /tmp/hello.pyad
rm -rf /tmp/hello.pybc
rm -rf /tmp/hello.pybd

say, i have foo.js and foo.coffee files, can we do something like rm -rf /tmp/foo.coffe[co] to delete the /tmp/foo.js.

You can make rather fancy methods but for those 2 files I'd just remove them with 1 command for each. Another example getting as close as possible to those 2 files...

rm /tmp/foo.[cj]*

would remove files like this ...

rm /tmp/foo.c*
rm /tmp/foo.j*

so it would include far more than just these 2 files.


It's a shell glob, similar to wildcards * and ? ...in bash, the filename pattern *.[co] matches all filenames that finish with .c or .o.

The difference with *.[co] versus *.c *.o or *.{c,o} is that the two latter patterns will expand to a dummy *.o if no .o files exist in the directory, while the *.[co] version won't.

Shell globs are useful for doing file operations in a non-case-sensitive way. For example, if you have a bunch of files with filenames that end with jpg, JPG, Jpg, JPg, etc... and you want to remove all of them, you can do:

rm *.[Jj][Pp][Gg]