6

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!

jbrock
  • 3,227
  • 23
  • 33
  • 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 02: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 02:32
  • I like your phrase "wonderful world of Linux" :) – WinEunuuchs2Unix Feb 13 '17 at 02: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 09:48
  • @OlivierDulac Using `for f in ./-*; do` did not work. It needed to be `for f in -*; do`. – jbrock Feb 15 '17 at 18:05
  • 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
  • @OlivierDulac I made a careless error with including the `^`. We are only looping through files that start with a dash. So, given the `rename` command does not follow with a `g` then it only removes the first instance anyways. Good point, your suggestion works after removing the `^`. Thanks – jbrock Feb 15 '17 at 19:36
  • [How to remove a file with name starting with “-r” using cli](https://superuser.com/q/689825/241386), [Unix: Files starting with a dash, -](https://superuser.com/q/120078/241386), [How to open files with forward dash in linux](https://superuser.com/q/603792/241386), [Can't rename a file the name of which starts with a hyphen](https://superuser.com/q/510337/241386), [How do I delete a file whose name begins with “-” (hyphen a.k.a. dash or minus)?](https://unix.stackexchange.com/q/1519/44425) – phuclv Aug 20 '18 at 05:41

2 Answers2

11

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.

muru
  • 193,181
  • 53
  • 473
  • 722
  • 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 02:37
2

I guess this should work as well

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