In terminal I can rename a single file that starts with a dash, i.e.

mv ./-file file

I can also rename all files in a directory that start with a dash, i.e.

for f in ./-*; do rename 's/-//' "$f"; done

However, how can I do this recursively. I have tried using the find command, the rename command, and a recursive for loop. By the way, a lot of the file names have more than one dash. I would only want to remove the first dash. Thanks!

  • It's a bad idea having file names beginning with - (dash) because that is used as a prefix to signify parametesr for many commands. ie $ mv a -a mv: invalid option -- 'a' Try 'mv --help' for more information. Feb 13, 2017 at 2:18
  • @WinEunuuchs2Unix Thanks. I named a bunch of files this way a few years back before I got to enjoy the wonderful world of Linux. This is why I'm renaming any files I had named this way.
    – jbrock
    Feb 13, 2017 at 2:32
  • I like your phrase "wonderful world of Linux" :) Feb 13, 2017 at 2:48
  • 1
    the proper way to loop over files is for f in ./-* ; do .... (this has many advantages, such as giving you possibility to give "$f" to any program without fearing it takes the filename as options. but there are other advantages as well, which I won't go into details here (look for stephaneChazelas answers, one has a lot of relevant details)) Feb 15, 2017 at 9:48
  • 1
    @jbrock: no, it should work (and avoid many other unpleasant side effects) but then the first argument to rename should be s/-// instead of s/^-// Feb 15, 2017 at 18:30

2 Answers 2


Using find and rename:

find . -iname '-*' -execdir rename -n 's:./-:./:' {} +

find . -iname '-*' matches all filenames beginning with a -, and then -execdir ... {} + runs the command with those filenames as arguments, after cding to the directory containing the files. This means that the command arguments always has filenames of the form ./-foo. Then it's easy to just match the - after the ./ in a regex.

  • Very nice. That is exactly what it seemed that needed to be done, cd to each directory that contains those files. Thanks! :)
    – jbrock
    Feb 13, 2017 at 2:37

I guess this should work as well

for i in $(find . -iname '-*') ; do mv $i $(echo $i | sed -e "s/-//"); done

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.