2016-07-30 1 views
2

Я пытаюсь переименовать несколько каталогов, содержащих «лихорадку», чтобы содержать «малярию». Инструкция состоит в том, чтобы сделать это без sed или переименовать. До сих пор мои ошибки включали в основном такие строки, какЕсть ли способ переименовать каталоги рекурсивно, не используя sed или переименовать?

mv: cannot stat ‘retest\nretest/Section-01\nretest/Section-02\nretest/Section-03\nretest/Section-04’: No such file or directory.

Лучший мой код - переименование каталогов на первом уровне.

Вот моя структура каталогов:

Fever-A/Malaria-A-A

Fever-B/Fever-B-A

Fever-B/Fever-B-B

Fever-C/Malaria-A

Fever-C/Fever-C-A

Fever-C/Fever-C-B

Fever-C/Fever-C-C-C

Fever-D/Malaria-A

Fever-D/Malaria-B

код у меня до сих пор:

#!/bin/bash 

# Access directory 
#cd $1 

# Find all subdirectories in $1 and load up array 
all=($(find $1 -type d)) 
#echo ${all[@]} 

# Loop through directories above 
for dir in ${all[@]} 
do 
    # echo "$dir" 
    cd $dir 
    # List files with "Section" in name 
    subdir=(:"Section*") 

    # A second loop for directories in each dir with "Section*" 
    for item in ${subdir[@]} 
    do 
      echo $item 
      echo "--------------------" 

      # Rename operation 
      mv $item ${item//Fever/Malaria} 
    done 
    cd $1 
done 

Другой подход, который я рассмотрел использует функцию, как это так, но он не работает: # !/Bin/Баш

rename(){ 
    old_names=($(find $1 -maxdepth 1 -type d)) 

    for item in ${old_names[@]} 
    do 
      if [[ $item = *Section* ]]; then 
        new_name=${item//Fever/Malaria} 
        mv $item $new_name 
      elif [[ $1 != $item ]]; then 
        rename $item 
      fi 

      rename $1 
    done 
} 

rename $1 
+1

Ограничьте оператор 'find' параметром' -name', например. 'find/path -type d -name" * Fever * "' Обычно 'while read -r fname; делать ... вещи ...; done <<(find/path -type d -name "* Fever *") ' –

+0

Используйте цитаты ..... –

+0

@KarolyHorvath любезно проиллюстрируйте. Я хотел бы лучше тебя понять. – SpaghettiThots

ответ

2

Ниже скрипт будет делать то, что вы ищете:

#/bin/bash 
renamer(){ 
dirname="${1##*/}" 
dirname="${dirname//fever/malaria}" 
basedir="${1%/*}" 
mv "$1" "${basedir}/${dirname}" 
} 
export -f renamer 
find /path/to/start/search/from -depth -type d -name "*fever*" -exec bash -c 'renamer "$1"' _ {} \; 

Смотрите это действие

$ tree . 
. 
|-- feverparent 
| |-- feverchild1 
| | `-- feverish_child 
| |  `-- totally_fever 
| `-- feverchild2 
|  `-- feverchild2_has_a_fever_child 
`-- myscript 

6 directories, 1 file 
$ ./myscript 
$ tree . 
. 
|-- malariaparent 
| |-- malariachild1 
| | `-- malariaish_child 
| |  `-- totally_malaria 
| `-- malariachild2 
|  `-- malariachild2_has_a_malaria_child 
`-- myscript 

6 directories, 1 file 

Примечания

  1. find говорит страница руководства

    -depth процесса содержимое каждого каталога перед самой директории.
    Действие -delete также означает -depth.

  2. См оболочки [ parameter expansion ], чтобы понять, что делается в моей функции renamer.

+0

Нет лучшего способа сделать это, я думаю;) ++ –

Смежные вопросы