how to remove files that could be with lower/upper case

for example, the file_name could be:

  • STOCK.Repo or
  • Stock.REPO or
  • stOCK.repo or
  • stock.repo
  • ... etc

I would run:

 rm -f $file_name

the goal is to remove file as stock.repo that could be in lower/upper case on remote machine


For Bash-specific solution:

$ shopt -s nocaseglob

and then run the rm command.

Note to unset this option, use shopt -u nocaseglob

For completeness, I would point out an alternative but less elegant solution:

$ rm [sS][tT][oO][cC][kK].[rR][eE][pP][oO]

You can do it using find command

find /path/to/directory -type f -iname stock\.repo -exec rm -f {} \;

But be very careful. It is working recursively from /path/to/directory. You should consider using maxdepth option, and getting more familiar with this command before running it on production system where permanent damage can be made.

  • 2
    Most find implementations also has -delete. For safety, if using -exec rm, you could instead use -ok rm. – Kusalananda Feb 20 '18 at 11:47
  • find knows -delete – user601 Feb 20 '18 at 14:52
  • Also, there is no need to escape the dot in the name pattern. – Kusalananda Feb 5 '19 at 13:24

With the zsh and ksh93 shells, you can turn case-insensitive matching on a per-glob basis:

  • zsh:

    set -o extendedglob # best in ~/.zshrc
    rm -- (#i)$filename
  • ksh93:

    rm -- ~(i:"$filename")

    Note however, that if there's no matching file a literal ~(i:stock.repo) would be passed to rm. And if that file exists, it would be removed (zsh above would fail with an error and not call rm at all in that case).

    You could however set the N flag in addition to the i flag:

    rm -- ~(Ni:"$filename")

    Then, in case of no-match, rm would be called, but with an empty argument (probably a bug caused by the quotes as it's meant to pass no argument at all then). You'd then get a rm: cannot remove '': No such file or directory kind of error but at least it wouldn't remove the wrong file.


I have done by using below method. Answer provided above is quite good. Below one is my try

ls -ltr | awk '{print $9}' | sed -n '/^STOCK.Repo$/Ip'  |awk '{print "rm" " " $1}'| sh
  • 1
    It's bad practice to parse ls, also you rely on the filenames returned from ls to have no spaces. This would remove not only STOCK.Repo but also STOCK.Repo1 etc. Furthermore, if a file is called STOCK.Repo;reboot this may reboot the machine. – Kusalananda Feb 20 '18 at 15:40
  • Yes i accept parsing ls output is bad pratice and i edited the answer so it will delete only the file STOCK.Repo – Praveen Kumar BS Feb 20 '18 at 16:25
  • Given the Linux tag, you could use gawk's ENDFILE functionality to avoid ls, an awk call, sed, and the pipe to sh with: gawk 'ENDFILE { IGNORECASE=1; if (FILENAME ~ /^stock\.repo$/) system("rm " FILENAME); }' * -- although I'd be cautious about removing files this way unless you knew (as we do here) exactly what the filenames are. – Jeff Schaller Feb 20 '18 at 18:53

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.