在Bash中使用一行命令重命名一个目录及其子目录
在Bash中使用一行命令重命名一个目录及其子目录
我有一个已经反编译的Android应用程序,我正在编写一个脚本来重命名目录。\n在反编译的文件夹中有一个路径:\nsmali/com/FOLDER/SUB-FOLDER
\n我想将现有的文件夹重命名为:\nsmali/com/NEW-NAME/SUB-NEW-NAME
\n我原本以为可以使用mv命令,但是在翻阅man页面时发现不能这样做。我尝试了以下命令:\nmv smali/com/FOLDER smali/com/FOLDER/SUB-FOLDER -t smali/com/NEW-NAME/SUB-NEW-NAME
\n这只适用于将多个文件移动到单个目标位置。\n编辑:\n现有的文件夹:\nsmali/com/FOLDER/SUB-FOLDER
\n我正在尝试同时重命名这两个文件夹,同时保留每个文件夹的内容。\n逐个重命名每个文件夹的示例是:\n
mv smali/com/FOLDER/ smali/com/NEW-NAME mv smali/com/NEW-NAME/SUB-FOLDER smali/com/NEW-NAME/SUB-NEW-NAME
问题的出现原因是作者想要用一行命令在Bash中重命名一个目录及其子目录。解决方法有以下几种:
方法一:
mv ./FOLDER ./NEW-NAME && mv ./NEW-NAME/SUB-FOLDER ./NEW-NAME/SUB-NEW-NAME
这种方法的优点是在父目录重命名成功之后才会进行子目录的重命名。
方法二:
f=FOLDER; t=NEW-NAME; mv "./$f/SUB-$f" "./$f/SUB-$t" && mv "./$f" "./$t"
这种方法先重命名子目录,然后再重命名父目录。
方法三:
p=(./*$f); [[ -d $p ]] && for s in $p/*$f; do mv "$s" "${s%$f}$t"; done && mv "$p" "${p%$f}$t"
这种方法使用了变量$f和$t来表示源目录和目标目录,通过循环遍历所有匹配的子目录进行重命名。
方法四:
find . -d -type d -name "*$f" -execdir sh -c 'mv -- "$0" "${0%$1}$2"' "{}" "$f" "$t" \;
这种方法使用了find命令,在所有子文件夹中查找匹配的目录并进行重命名。
最后,作者祝愿读者愉快!
问题原因:
这个问题的出现是因为原始的解决方法中存在一些问题,导致无法正确重命名目录及其子目录。
解决方法:
原始的解决方法是使用find命令和awk命令来生成mv命令,并将这些命令写入cmds文件中,然后通过执行sh cmds来执行这些命令。然而,该方法存在一些问题,包括生成的命令中未创建新目录、安全性问题等。因此,需要对原始的解决方法进行修改。
修改后的解决方法是在生成mv命令之前先创建新目录,然后再执行mv命令进行重命名。这样可以确保新目录存在,并且避免安全性问题。
文章内容如下:
在Bash中使用一行命令重命名目录及其子目录
有一个问题需要解决:如何使用一行命令来重命名目录及其子目录。下面是一个解决方法:
find . -path '.*com/FOLDER/SUBFOLDER' | awk '{new_dir=$1; sub("/FOLDER/SUBFOLDER","/NEW/SUBNEW", $new_dir); printf("mkdir -p %s\nmv %s %s\n", $new_dir, $1, $new_dir);}' > cmds
这个解决方法使用了find命令和awk命令来生成mv命令,并将这些命令写入了cmds文件中。然后,可以通过执行sh cmds来执行这些命令。
然而,这个解决方法存在一些问题。首先,生成的命令中没有创建新目录,这意味着如果新目录不存在,mv命令将无法成功执行。其次,从安全性的角度考虑,这种方法是不可取的,因为它将字符串作为代码进行解析,存在潜在的安全风险。
为了解决这些问题,我们需要对原始的解决方法进行修改。修改后的解决方法如下:
find . -path '.*com/FOLDER/SUBFOLDER' | awk '{new_dir=$1; sub("/FOLDER/SUBFOLDER","/NEW/SUBNEW", $new_dir); printf("mkdir -p %s\nmv %s %s\n", $new_dir, $1, $new_dir);}' > cmds
修改后的解决方法在生成mv命令之前先使用mkdir命令创建新目录,然后再执行mv命令进行重命名。这样可以确保新目录存在,并且避免安全性问题。
需要注意的是,修改后的解决方法仍然需要在执行之前对生成的命令进行验证,以确保其正确性。这是因为生成的命令是通过解析数据作为代码来执行的,存在一定的安全风险。
通过对原始解决方法的问题进行分析和修正,我们可以使用一行命令来重命名目录及其子目录。在执行之前,需要验证生成的命令以确保其正确性,并采取一些安全措施来避免潜在的安全风险。这种解决方法在处理重要数据时非常有用,因为验证即将执行的命令总是比较好的做法。
参考来源:https://stackoverflow.com/questions/13588285
在Bash中使用一行代码重命名目录及其子目录的问题是因为需要一种简洁的方法来重命名多个目录。下面是问题的解决方法:
首先,定义一个函数rename_pieces,参数为old和new。函数内部的操作如下:
1. 检查new是否包含子目录,如果是,则使用mkdir -p命令创建相应的子目录。
2. 使用mv -T命令将old目录重命名为new目录。
如果只想重命名SUB-FOLDER目录,可以使用以下代码:
rename_pieces() { local old=$1 new=$2 [[ $new = */* ]] && mkdir -p -- "${new%/*}" mv -T -- "$old" "$new" }
如果想同时重命名FOLDER和SUB-FOLDER目录,可以使用以下代码:
首先定义一个函数log_or_run,用于判断是只记录命令还是实际运行命令。
然后定义函数rename_pieces,参数为old和new。函数内部的操作如下:
1. 使用while循环,判断old和new是否有公共部分,如果有,则将公共部分添加到common变量中,并更新old和new。
2. 使用while循环,判断old和new是否都存在,如果是,则使用log_or_run函数记录或运行mv -T命令,将old目录重命名为new目录,并更新common、old和new。
3. 最后,使用log_only=1调用rename_pieces函数,将smali/com/FOLDER/SUB-FOLDER目录重命名为smali/com/NEW/SUBNEW目录。
整个过程如下:
log_or_run() { if [[ $log_only ]]; then printf '%q ' "$@" >&2 printf '\n' >&2 else "$@" fi } rename_pieces() { local old=$1 new=$2 common while [[ ${old%%/*} = "${new%%/*}" ]]; do common+=/"${old%%/*}" old=${old#*/}; new=${new#*/} done while [[ $old && $new ]]; do log_or_run mv -T -- "${common#/}/${old%%/*}" "${common#/}/${new%%/*}"; echo common+=/"${new%%/*}" [[ $old = */* && $new = */* ]] || return old=${old#*/}; new=${new#*/} done } log_only=1 rename_pieces smali/com/FOLDER/SUB-FOLDER smali/com/NEW/SUBNEW
以上代码在输出中显示了实际运行的命令,包括将smali/com/FOLDER目录重命名为smali/com/NEW目录和将smali/com/NEW/SUB-FOLDER目录重命名为smali/com/NEW/SUBNEW目录。如果去掉log_only=1,则代码将实际运行这些命令。