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. – WinEunuuchs2Unix Feb 13 '17 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 '17 at 2:32
  • I like your phrase "wonderful world of Linux" :) – WinEunuuchs2Unix Feb 13 '17 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)) – Olivier Dulac Feb 15 '17 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/^-// – Olivier Dulac Feb 15 '17 at 18:30

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 '17 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.