tags:

views:

171

answers:

6

I run unsuccessfully in Mac

mv .* *

and

mv .* ./*

My files disappeared into thin air.

How can you convert dot-files to non-dotfiles safely?

+4  A: 

You can't use mv to rename multiple files like that. What you want is mmv (get it here).

mmv .\* \#1

You have to escape the asterisk to prevent bash from expanding it. Use the -n flag to do a test run to make sure what will happen is what you want.

You could also do this in shell scripting but I much prefer mmv because the -n flag shows what it would do. You'd have to alter your script to echo instead of mv, which seems more dangerous than dropping the -n flag (especially when you get more complicated.

Colin Burnett
+5  A: 
for i in `ls -d .*`; do mv $i "`echo $i | sed 's/^.//'`"; done

or, much easier,

rename 's/^.//' `ls -d .*`

if your system have got it.

In zsh, you could just use .* safely, but in bash you'll have to use ls -d .*

alamar
bash should always error out for . and ..; I don't think any sane implementation could possibly succeed with "mv . ''" or "mv .. .".
Adam Rosenfield
Absolutely. But then it would not suck; and bash just can't not.
alamar
"ls -1" is not necessary: ls automatically outputs in 1 column if stdout is not a terminal device (e.g. if it's outputting to a pipe).
Adam Rosenfield
Fixed that. Never needed ls in this case anyway.
alamar
@alamar: How deep does your 1st command go? -- I run it by accident at Home.
Masi
@alamar: Your 1st command is dangerously powerful. Does the second command go to subdirectories too?
Masi
Both would only affect files and directores (but not their contents) in the current directory. They're essentially equal.
alamar
+1  A: 

i don't know what type of system you're on, but it looks unix like, i would do

ls -1 .?* | cut -b1- | xargs -i{} mv .{} {}

this lists, everything that starts with a ., but isn't . or .., then cut the first column off, then pipe that list to a move command

Roy Rico
+1  A: 

The tricky part about this is selecting dotfiles without selecting "." and "..".

  • ls .??* is sometimes used for this, since it forces the filenames to be three or more characters long. There is a risk though, of overlooking a dotfile with a short name, such as ".x"
  • ls -d .* prevents directories from being expanded, but it doesn't filter out "." or ".."
  • The find command could be used, as in find . -maxdepth 1 -type f -name '.*'. The maxdepth limits it to the current directory and not subdirectories. The -type f limits it to files, eliminating directories such as "." and "..". Then again, maybe you want to rename the .ssh directory to ssh.

Here's an alternative that selects dotfiles while avoiding "." and "..".

ls -A | sed -n 's/^\.\(.*\)/mv ".\1" "\1"/p' | bash

The -A lists all files and dotfiles, yet eliminates "." and ".." for us. Then the sed command selects only those lines with "." as the first character, and prints out appropriate "mv" commands, complete with quotes in case you have a bizarre dotfilename with a space in it.

Run it without the "| bash" first, to see what mv commands are generated.

Pete TerMaat
+1  A: 

In Linux, there is usually a rename utility available (a perl script, if I am not mistaken):

rename 's/^.//' .*

It is available on a Mac. You can install it by following tips at here.

Svante
I am trying to install the command at http://stackoverflow.com/questions/915174/unable-to-install-linuxs-rename-to-mac and to add it to MacPorts at http://stackoverflow.com/questions/915144/unable-to-find-port-dependencies-for-rename-in-util-linux-for-macports
Masi
A: 

Even simpler:


for x in .*; do mv $x ${x/./}; done    

optixx