有没有办法在不使用 sed 或 rename 的情况下递归重命名目录? [英] Is there a way to rename directories recursively without using sed or rename?
问题描述
我正在尝试将一些包含Fever"的目录重命名为包含Malaria".指令是在没有 sed 或重命名的情况下进行.到目前为止,我的错误主要包括像
这样的行mv: cannot stat 'retest\nretest/Section-01\nretest/Section-02\nretest/Section-03\nretest/Section-04': 没有那个文件或目录
.>
我的代码所做的最好的事情是在第一级重命名目录.
这是我的目录结构:
Fever-A/疟疾-A-A
Fever-B/Fever-B-A
Fever-B/Fever-B-B
Fever-C/疟疾-A
Fever-C/Fever-C-A
Fever-C/Fever-C-B
Fever-C/Fever-C-C-C
Fever-D/疟疾-A
Fever-D/疟疾-B
我到目前为止的代码是:
#!/bin/bash# 访问目录#cd $1# 查找 $1 中的所有子目录并加载数组all=($(find $1 -type d))#echo ${all[@]}# 遍历上面的目录对于 ${all[@]} 中的目录做# echo "$dir"cd $目录# 列出名称为Section"的文件subdir=(:"Section*")# 使用Section*"对每个目录中的目录进行第二次循环对于 ${subdir[@]} 中的项目做回声 $item回声--------------------"# 重命名操作mv $item ${item//发烧/疟疾}完毕光盘 $1完毕
我考虑过的另一种方法是使用这样的函数,但它也不起作用:#!/bin/bash
rename(){old_names=($(find $1 -maxdepth 1 -type d))对于 ${old_names[@]} 中的项目做if [[ $item = *Section* ]];然后new_name=${item//发烧/疟疾}mv $item $new_nameelif [[ $1 != $item ]];然后重命名 $item菲重命名 $1完毕}重命名 $1
以下脚本将满足您的需求:
#/bin/bash重命名(){目录名="${1##*/}"dirname="${dirname//发烧/疟疾}"basedir="${1%/*}"mv "$1" "${basedir}/${dirname}"}导出 -f 重命名器find/path/to/start/search/from -depth -type d -name "*fever*" -exec bash -c 'renamer "$1"' _ {} \;
看到它的动作
$ 树..|-- 发烧父母||-- 发烧孩子1||`--feverish_child||`--totally_fever|`--feverchild2|`--feverchild2_has_a_fever_child`--我的脚本6个目录,1个文件$ ./我的脚本$树..|-- 疟疾父母||-- 疟疾儿童1||`-- malariaish_child||`--totally_malaria|`--疟疾儿童2|`-- malariachild2_has_a_malaria_child`--我的脚本6个目录,1个文件
注意事项
<块引用>find
联机帮助页说-depth 在目录本身之前处理每个目录的内容.
-delete 操作也意味着 -depth.参见 shell [参数扩展] 以了解我的函数
renamer
中正在执行的操作.
I am trying to rename a few directories that contain "Fever" to contain "Malaria" instead. The instruction is to do it without sed or rename. So far, my errors include mostly lines like
mv: cannot stat ‘retest\nretest/Section-01\nretest/Section-02\nretest/Section-03\nretest/Section-04’: No such file or directory
.
The best my code have done is rename directories in the first level.
Here's my directory structure:
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
The code I have so far is :
#!/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
Another approach I've considered is using a function like so, but it's not working either: #!/bin/bash
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
Below script will do what you're looking for :
#/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"' _ {} \;
See it action
$ 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
Notes
find
manpage says-depth Process each directory's contents before the directory itself.
The -delete action also implies -depth.See shell [ parameter expansion ] to understand what is being done inside my function
renamer
.
这篇关于有没有办法在不使用 sed 或 rename 的情况下递归重命名目录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!