2

I'm trying to revert a change I made via rename.

I was renaming files in a subfolder, then without thinking, tried to clear the .. from names using:

rename "s/.././" *

Now I have a folder of 600 files with the 2 first letters of each filename changed to .zzyGir*

Is there any way to change the "." back to the first letters of each filename without losing the whole file?

I've tried different things with no luck, such as:

rename "s/./Di/; *

I'm open to one-file-at-a-time solutions, too, I'm primarily trying to avoid losing the files.

1
  • Reformatted question to more clearly identify the commands involved, and to reduce noise to make it easier to grok the details of the situation quickly. Jul 10, 2015 at 18:54

2 Answers 2

2

The first two letters are history. No chance to get them back. But you can rename the files to strip the leading . with the procedure below

Be sure to have the bash in a terminal

bash

Go into your folder with the wrong filenames

shopt -s dotglob
rename -n 's/^\./Di/' *

If all looks fine

rename 's/^\./Di/' *

Finish with

shopt -u dotglob

Explanation

  • rename -n "s/^\./Di/" *

    • -n

      No action: print names of files to be renamed, but don't rename.

    • /^\./

      • ^ assert position at start of the string

      • \. matches the character . literally

  • shopt -s dotglob & shopt -u dotglob

    • shopt

      shopt [-pqsu] [-o] [optname …]
      

      Toggle the values of settings controlling optional shell behavior.

    • -s

      Enable (set) each optname.

    • -u

      Disable (unset) each optname.

    • dotglob

      If set, Bash includes filenames beginning with a . in the results of filename expansion.


Example

$ ls -oag
total 88
drwxrwxr-x   2  4096 Jul 17 17:16 .
drwxr-xr-x 226 86016 Jul 17 17:13 ..
-rw-rw-r--   1     0 Jul 17 17:16 .foo

$ rename "s/^\./Di/" *

$ ls -oag
total 88
drwxrwxr-x   2  4096 Jul 17 17:16 .
drwxr-xr-x 226 86016 Jul 17 17:13 ..
-rw-rw-r--   1     0 Jul 17 17:16 Difoo

I'm not sure, what you mean with this

Is there any way to change the "." back to the first letters of each filename

Do you mean something like this?

.zzyGir -> zzzzGir

If yes, then use this commands in a bash:

shopt -s dotglob
rename -n 's/^\.(..)(.*)/$1$1$2/' *

Check the results and rename with

rename 's/^\.(..)(.*)/$1$1$2/' *

And finally again

shopt -s dotglob
1
  • +1, on a side note you don't have to enable dotglob to match dotfiles, you can just match them with this globbing pattern: .*
    – kos
    Jul 17, 2015 at 16:19
0

As I understand you have a folder with files such as below:

ls -la

drwxrwxr-x 2 ron ron 4096 Jul 17 20:50 .
drwxrwxr-x 3 ron ron 4096 Jul 17 20:47 ..
-rw-rw-r-- 1 ron ron    0 Jul 17 20:47 .abc
-rw-rw-r-- 1 ron ron    0 Jul 17 20:47 .Gyr
-rw-rw-r-- 1 ron ron    0 Jul 17 20:47 .hig123
-rw-rw-r-- 1 ron ron    0 Jul 17 20:47 .zyz

and you want to remove . from all the file names to make it:

abc
Gyr
hig123
zyz

For this you can use find and rename:

find . ! -path . -type f -name ".*" -exec rename -n "s/.\/.//" {} \;

The above command (i.e with the -n) is a dry-run:

find . ! -path . -type f -name ".*" -exec rename -n "s/.\/.//" {} \;
rename(./.zyz, zyz)
rename(./.abc, abc)
rename(./.Gyr, Gyr)
rename(./.hig123, hig123)

Run it without -n to actually change the file names:

find . ! -path . -type f -name ".*" -exec rename "s/.\/.//" {} \;
ls -la
total 8   
drwxrwxr-x 2 ron ron 4096 Jul 17 20:59 .
drwxrwxr-x 3 ron ron 4096 Jul 17 20:47 ..
-rw-rw-r-- 1 ron ron    0 Jul 17 20:47 abc
-rw-rw-r-- 1 ron ron    0 Jul 17 20:47 Gyr
-rw-rw-r-- 1 ron ron    0 Jul 17 20:47 hig123
-rw-rw-r-- 1 ron ron    0 Jul 17 20:47 zyz

You must log in to answer this question.