简体   繁体   中英

Script to replace/delete characters in direcory and file names (work in progress)

I am trying to delete a set of characters like single quote (') and spaces from file names and directories. Example, I have:
Directory I'm confused which contains file you're right

So far, I have been able to create a short script:

#!/bin/sh
for f in *; do mv "$f" `echo $f | tr ' ' '_'`; done
for f in *; do mv "$f" `echo $f | tr -d \'`; done

which renames the dir to Im_confused as intended. The file in the directory of course is not affected.

How can I replace and delete characters in subdirectories as well?

Looking forward to hear your suggestions!

For example, for depth 2, the command is:

REP_CHARS=" →" # Characters to replace
DEL_CHARS="'," # Characters to delete
find . -maxdepth 2 | sort -r |
  sed -n -e '/^\.\+$/!{p;s#.\+/#&\n#;p}' |
  sed "n;n;s/[$DEL_CHARS]//g;s/[$REP_CHARS]/_/g" |
  sed "n;N;s/\n//" |
  xargs -L 2 -d '\n' mv 2>/dev/null
  1. Use find with -maxdepth .
  2. Use sort to order from the deepest.
  3. Use sed to replace only the end part.
  4. Use xargs to perform mv.
[Original]

├── I'm confused
│   ├── I'm confused
│   │   └── you're right
│   ├── comma, comma
│   └── you're right
└── talking heads-love → building on fire
    └── talking heads-love → building on fire

[After]

├── Im_confused
│   ├── Im_confused
│   │   └── you're right
│   ├── comma_comma
│   └── youre_right
└── talking_heads-love___building_on_fire
    └── talking_heads-love___building_on_fire

I would use this rename script:

#!/bin/sh
for f in *; do
    g=$(printf '%s' "$f" | tr -s '[:space:]' _ | tr -d "'")
    [ "$f" != "$g" ] && mv -v "$f" "$g"
done

and this find invocation

find . -depth -execdir /absolute/path/to/rename.sh '{}' +
  • -depth does a depth-first descent into the file hierarchy so the files are renamed before their parent directories
  • -execdir performs the command in the directory where the file is found, so the value of $f only contains the filename not its directory as well.

Demo

$ mkdir -p "a b/c d/e f"
$ touch a\ b/c\ d/e\ f/"I'm confused"
$ touch "a file with spaces"
$ tree
.
├── a\ b
│   └── c\ d
│       └── e\ f
│           └── I'm\ confused
├── a\ file\ with\ spaces
└── rename.sh

3 directories, 3 files

$ find . -depth -execdir /tmp/rename.sh '{}' +
renamed 'a b' -> 'a_b'
renamed 'a file with spaces' -> 'a_file_with_spaces'
renamed "I'm confused" -> 'Im_confused'
renamed 'e f' -> 'e_f'
renamed 'c d' -> 'c_d'

$ tree
.
├── a_b
│   └── c_d
│       └── e_f
│           └── Im_confused
├── a_file_with_spaces
└── rename.sh

3 directories, 3 files

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM