【问题标题】:Rename all files in directory and (deeply nested) sub-directories重命名目录和(深度嵌套的)子目录中的所有文件
【发布时间】:2018-07-18 20:29:28
【问题描述】:

什么是重命名目录和子目录中所有文件(递归)的shell命令?

我想在所有目录和子目录中从filename.scss_filename.scss的所有以*scss结尾的文件添加下划线。

我找到了与此相关的答案,但大多数(如果不是全部)都要求您知道文件名本身,我不希望这样做,因为文件名不同并且需要记住很多,甚至手动键入它们,其中一些深深嵌套在目录中。

【问题讨论】:

  • 尝试循环查找
  • Find 在查找文件时效果很好,但在我想重命名找到的文件时不起作用(文件名未发出)
  • 我已经尝试过这个find ./src/components -iname "*.scss" 并且这会获取文件,但是我将如何获取每个文件名并为其附加下划线?像find ./src/components -iname "*.scss" | mv each-file-name to _each-file-name 这样的东西?另外,find,找到所有东西,所以不确定在循环中这是否会有所作为。

标签: bash shell unix


【解决方案1】:

编辑:我的印象是bash -c 位对于找到的元素的多次扩展是必要的;阿努巴瓦的回答证明我错了。我现在将那一点留在答案中,因为它适用于 OP。

find . -type f -name *scss -exec bash -c 'mv $1 _$1' -- {} \;
  • find . -- 在当前目录中查找(递归)
  • -type f -- 文件
  • -name *scss -- 匹配模式 *scss
  • -exec -- 为找到的每个元素执行
  • bash -c '...' -- 在子shell中执行命令
  • -- -- 结束选项解析
  • {} -- 扩展为找到的元素的名称(成为bash -c 命令的位置参数)
  • \; -- 结束-exec 命令

【讨论】:

  • execexecdir?
  • 超级!它有效,但必须使用execdir,因为我认为exec 不会在目录中执行。
  • @brandNew:使用-exec,您将获得相对于源目录的元素的完整路径,即mv ./foo/bar/baz.scss ./foo/bar/_baz.scss。使用-execdir,您可以转到执行命令的元素的子目录,即mv baz.scss _baz.scss。无论哪种方式都有效; find 的手册页推荐后者。我承认我自己直到现在才知道-execdir。你生活和学习。 ;-)
  • 当然。干杯。
【解决方案2】:

您可以在此处使用-execdir 选项:

find ./src/components -iname "*.scss" -execdir mv {} _{} \;

【讨论】:

  • 第一个答案有效。但这也很有用(本来可以的),所以点赞!
  • OK... 现在我必须回溯并找出为什么我认为每个 -exec 只能有一个 {} 并且您需要 bash -c 位进行多次扩展。 ?:-\
  • @DevSolar:如果它不起作用,我就不会发布。它在我的 Mac 上运行良好 find
【解决方案3】:

您已接近解决方案:

find ./src/components -iname "*.scss" -print0 | xargs -0 -n 1 -I{} mv {} _{}

在这种方法中,“循环”由 xargs 执行。我更喜欢这个解决方案,而不是在 find 中使用 -exec。语法对我来说很清楚。

此外,如果您想重复该命令并避免在已处理的文件中重复添加下划线,请使用正则表达式仅获取尚未处理的文件:

find ./src/components -iregex ".*/[^_][^/]*\.scss" -print0 | xargs -0 -n 1 -I{} mv {} _{}

通过添加 -print0/-0 选项,您还可以避免空格问题。

【讨论】:

  • 第一个答案有效。但这也很有用(本来可以的),所以点赞!
【解决方案4】:
#!/bin/sh

EXTENSION='.scss'
cd YOURDIR

find . -type f | while read -r LINE; do
  FILE="$( basename "$LINE" )"

  case "$LINE" in
    *"$EXTENSION")
      DIRNAME="$( dirname "$LINE" )"
      mv -v "$DIRNAME/$FILE" "$DIRNAME/_$FILE"
    ;;
  esac
done

【讨论】:

  • 感谢您,但问题已得到解答并已接受。将来,请考虑解释为什么某事有效,而不仅仅是直接的解决方案或对问题或问题的回答:)。干杯。
猜你喜欢
  • 2021-01-25
  • 1970-01-01
  • 1970-01-01
  • 2014-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-08
相关资源
最近更新 更多