【问题标题】:Recursively Rename Files and Directories with Bash on macOS在 macOS 上使用 Bash 递归地重命名文件和目录
【发布时间】:2021-06-23 12:12:30
【问题描述】:

我正在编写一个脚本,它将执行一些操作,其中一个操作是在文件名和目录名中查找所有出现的字符串,并将其替换为另一个字符串。

到目前为止我有这个

find . -name "*foo*" -type f -depth | while read file; do
    newpath=${file//foo/bar}
    mv "$file" "$newpath"
done

只要文件的路径不包含foo,它就可以正常工作,但这不能保证。

我觉得解决这个问题的方法是先只更改文件名,然后再返回并更改目录名,但即便如此,如果您的结构中有多个包含 foo 的目录它,它将无法正常工作。

有没有办法使用内置的 macOS 工具来做到这一点? (我说是内置的,因为这个脚本将分发给我们组织中的其他一些人,它不能依赖任何要安装的包)。

【问题讨论】:

  • 您可以将路径名与文件名分开,然后进行替换,然后在重命名之前重新构建/连接它们?

标签: bash macos find rename


【解决方案1】:

将路径名与文件名分开,类似于。

#!/usr/bin/env bash

while read -r file; do
  path_name="${file%/*}"; printf 'Path is %s\n' "$path_name"
  file_name="${file#"$path_name"}"; printf 'Filename is %s\n' "$file_name"
  newpath="$path_name${file_name//foo/bar}"
  echo mv -v "$file" "$newpath"
done < <(find . -name "*foo*" -type f)

看看basenamedirname

printf 只是用来显示路径和文件名。

脚本只是将文件名中的foo替换为bar,也可以使用路径名来完成,只需使用相同的语法即可。

newpath="${path_name//bar/more}${file_name//foo/bar}"

所以重命名 path_name 和 file_name。

或者像你的想法一样重命名路径名,然后文件名也是一个选项。

path_name="${file%/*}"
file_name="${file#"$path_name"}"
new_pathname="${path_name//bar/more}"

mv -v "$path_name" "$new_pathname"

new_filename="${file_name//foo/bar}"

mv -v "${new_pathname%/*}$file_name" "$new_pathname$new_filename"

没有使用额外的外部工具/实用程序,脚本使用的除外。

如果您对结果/输出感到满意,请删除 echo

【讨论】:

  • 我试试看。
  • 这适用于文件名,但不能与文件名同时更改目录路径,因为目录不存在。
  • 是的,目录必须存在才能重命名。
  • 我最终得到了与您在这里所拥有的非常相似的东西并且它有效。感谢您的帮助。
【解决方案2】:

您可以使用-execdir 仅对相关目录中的文件名(基本名称)运行命令:

find . -depth -name '*foo*' -execdir bash -c 'mv -- "${1}" "${1//foo/bar}"' _ {} \;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 2014-02-07
    • 2010-12-13
    • 2014-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多