13

I hid some files using the command:

mv * .*

but now I am unable to find them. I tried using:

mv .* *

but nothing happened (an error was shown). If I run:

ls -la

it's showing:

total 8  
drwxrwxr-x 2 abhishek abhishek 4096 Mar  9 20:46 .  
drwxrwxr-x 4 abhishek abhishek 4096 Mar  9 20:46 ..  

Is there any way to recover my hidden files?

1
  • The key thing here is that the glob stars * are processed before mv ever gets the chance to look at the command line. You can use $ echo mv .* * to preview the command line before running it, so you can see what mv sees.
    – jpaugh
    Mar 11, 2021 at 18:52

1 Answer 1

44

Your files are not hidden, you have moved all files (and directories if any) one directory up.

This happens because mv * .* won't work as you think it will. The command mv will only move one file to one file (rename) or move one or multiple files to a directory. It won't move multiple files to multiple files with some smart renaming.


What happened?

Let's assume we have one directory and 3 files in our directory:

dir1
file1
file2
file3

Some Shells (e.g. bash, dash, ...) will expand your command to:

mv dir1 file1 file2 file3 . ..

Your expanded command fits the second form of the SYNOPSIS you find at man mv:

mv [OPTION]... SOURCE... DIRECTORY

Note the . and ..:

  • . is the current directory,
  • .. is one directory up.

The command means: move dir1, file1, file2 and file3 and . to ..; It will also essentially give an error, something like:

mv: cannot move '.' to '../.'

But given you have write permission in that directory, all other files have been moved. You can find your files in .. (= one directory up). However, files with same name have been overwritten and you won't know which files was in which directory before.


If you had a subdirectory .hidden-dir, it would have expanded to:

mv dir1 file1 file2 file3 . .. .hidden-dir

Then, all files would have been moved to .hidden-dir. However, this seems not the case for you, because the you would have seen .hidden-dir in your ls -la output.


How to fix

Run:

mv ../dir1 ../file1 ../file2 ../file3 .

However, you need to know the names.


What you should have used

mmv '*' '.#1'

or

rename 's/^/./' *
9
  • 4
    and you won't know which files was in which directory before. - all the files that were moved will have the same ctime - ls -a -lcrt is useful to sort files by ctime with the most recent ones at the bottom. Mar 10, 2021 at 15:25
  • 8
    It might have moved one directory up. It will move to whatever directory shows up last in the expansion of .*, which might some hidden directory, especially if this was done in a user's home directory or a directory under version control. I would recommend running ls -1d | tail -n1 in that directory. (in this case, he had an otherwise empty directory ... but others might not be so fortunate)
    – Joe
    Mar 10, 2021 at 15:47
  • True, I added that information to the question. However, it is not the case here as OP issued ls -la without output.
    – pLumo
    Mar 10, 2021 at 16:24
  • 2
    Shell also matters. For example, zsh doesn't match files .. nor . for any glob.
    – JoL
    Mar 10, 2021 at 23:34
  • 1
    Note that mmv and rename may not be available everywhere. It would also probably be a good thing to emphasise the fact its mmv` and not mv for the hurried reader .
    – jcaron
    Mar 11, 2021 at 13:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .