Linux在目录之前重命名文件
Posted
技术标签:
【中文标题】Linux在目录之前重命名文件【英文标题】:Linux rename files before directories 【发布时间】:2018-05-01 16:09:33 【问题描述】:我有以下命令运行到小写文件/目录,替换 .使用 _ 和其他各种操作。它的问题是它似乎首先尝试重命名目录,然后找不到它下面的文件。有没有办法先重命名目录中的所有文件,然后递归地重命名目录本身?例如
目录1 文件1 文件2 目录1 文件1 文件2 目录2 文件1 目录2 文件1 文件2我的代码是
while IFS= read -rd '' entry; do
entry="$entry#./" # strip ./
if [[ -d $entry ]]; then
rename 'y/A-Z/a-z/; s/ /_/g; s/_-_/-/g; s/sometext//g; s/_extras/-extras/g' "$entry"
else
rename 'y/A-Z/a-z/; s/\.(?=.*\.)/_/g; s/ /_/g; s/_-_/-/g; s/sometext//g; s/_extras/-extras/g' "$entry"
fi
done < <(find . -iname '*' -print0)
【问题讨论】:
您需要使用递归来一次性实现,或者先重命名文件然后再重命名目录 我会使用find
创建一个列表,并根据目录/文件深度对其进行自下而上的排序。
【参考方案1】:
这是使用递归的示例 UNTESTED 代码:
recurse()
for entry in "$1"/*; do
entry="$entry#./" # strip ./
if [[ -d $entry ]]; then
recurse $entry
rename 'y/A-Z/a-z/; s/ /_/g; s/_-_/-/g; s/sometext//g; s/_extras/-extras/g' "$entry"
else
rename 'y/A-Z/a-z/; s/\.(?=.*\.)/_/g; s/ /_/g; s/_-_/-/g; s/sometext//g; s/_extras/-extras/g' "$entry"
fi
done
recurse "/home"
【讨论】:
【参考方案2】:你看过this answer? 您的场景更复杂,但看起来他们在递归方面遇到了同样的困难。
【讨论】:
【参考方案3】:我正在考虑类似的事情:
find /path |awk -F/ 'print NF,$0' |sort -r -n -k 1 |cut -f2- -d' ' |\
while IFS= read -rd '' entry; do
# ...
done
想法是在每一行前面加上/
的编号,并根据该字段反向排序:
4 /path/dir1/file1 4 /path/dir2/file2 3 /路径/目录1 3 /path/dir2 2 /路径
然后切掉第一列。这样您就可以自下而上处理条目以避免重命名问题。
【讨论】:
这看起来应该可以,但是当我尝试处理文件/目录时,我收到一条错误消息,提示“文件名太长:”。我可能会补充一点,我正在使用 bash for Windows (Ubuntu) 并在 NTFS 磁盘上运行命令,如果这有什么不同的话 从哪里来,重命名? 是的,我认为如果我运行它,它工作正常 find 。 |awk -F/ 'print NF,$0' |sort -r -n -k 1 |cut -f2- -d' ' |\ entry="$entry#./" # strip ./ if [ [ -d $entry ]];然后 echo $entry else echo $entry fi 完成 您可以使用dirname
和basename
分割条目,例如dirname=$(dirname "$entry")
,然后是pushd "$dirname"; rename $rules "$basename"; popd
。以上是关于Linux在目录之前重命名文件的主要内容,如果未能解决你的问题,请参考以下文章