【问题标题】:Linux rename files before directoriesLinux在目录之前重命名文件
【发布时间】: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 创建一个列表,并根据目录/文件深度对其进行自下而上的排序。

标签: linux rename file-rename


【解决方案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 完成
      • 您可以使用dirnamebasename 分割条目,例如dirname=$(dirname "$entry"),然后是pushd "$dirname"; rename $rules "$basename"; popd
      猜你喜欢
      • 1970-01-01
      • 2012-04-01
      • 2012-04-26
      • 2015-10-08
      • 2011-06-14
      • 2017-03-28
      • 2013-10-30
      • 2013-07-06
      • 2013-09-13
      相关资源
      最近更新 更多