在bash脚本中获取祖父目录 - 为其路径中的目录重命名文件

use*_*155 3 linux bash centos path batch-rename

我有以下脚本,当我得到一堆需要重命名为包含它们的目录名的文件时,我通常会使用它.

现在的问题是我需要将文件重命名为两个级别的目录.如何获取祖父目录以使其工作?

有了以下我得到的错误就像这个例子:"mv:无法移动./48711/zoom/zoom.jpg./48711/zoom/./48711/zoom.jpg:没有这样的文件或目录".这是在CentOS 5.6上运行的.

我希望最终文件命名为:48711.jpg

#!/bin/bash

function dirnametofilename() {
  for f in $*; do
    bn=$(basename "$f")
    ext="${bn##*.}"
    filepath=$(dirname "$f")
    dirname=$(basename "$filepath")
    mv "$f" "$filepath/$dirname.$ext"
  done
}

export -f dirnametofilename

find . -name "*.jpg" -exec bash -c 'dirnametofilename "{}"'  \;

find .
Run Code Online (Sandbox Code Playgroud)

Onl*_*Cop 7

另一种方法可以是使用

(cd ../../; pwd)
Run Code Online (Sandbox Code Playgroud)

如果这是在任何顶级的路径,如执行/,/usr/或者/usr/share/,你会得到一个有效的目录/,但是当你深入一层,你会开始看到的结果:/usr/share/man/将返回/usr,/my/super/deep/path/is/awesome/将返回/my/super/deep/path,等等.

您也可以将其存储在变量中:

GRANDDADDY="$(cd ../../; pwd)"
Run Code Online (Sandbox Code Playgroud)

然后将其用于脚本的其余部分.


mkl*_*nt0 3

注意:
*这个答案解决了OP的具体问题,在其上下文中“祖父母目录”意味着:包含文件的目录的父目录(从文件的角度来看,它是祖父母路径)。
* 相比之下,考虑到问题的通用标题,这里的其他答案(仅)集中于获取目录的祖父母目录;一般问题的简洁答案获取grandParentDir=$(cd ../..; printf %s "$PWD")完整路径,并且grandParentDirName=$(cd ../..; basename -- "$PWD")获取目录。仅名称。

请尝试以下操作:

find . -name '*.jpg' \
  -execdir bash -c \
   'old="$1"; new="$(cd ..; basename -- "$PWD").${old##*.}"; echo mv "$old" "$new"' - {} \;
Run Code Online (Sandbox Code Playgroud)

注意:为了安全起见,将其删除以执行实际的重命名 echomv

  • -execdir ..\;在包含给定匹配文件并展开的特定目录中执行指定命令{}到每个文件的文件名。

  • bash -c用于执行一个小的临时脚本:

    • $(cd ..; basename -- "$PWD")确定包含该文件的目录的目录名称,从文件的角度来看,这是祖父路径。

    • ${old##*.}是一个 Bash参数扩展,返回输入文件名的后缀(扩展名)。

    • 请注意如何将手头的文件名作为第二个{}参数传递给命令以便绑定到,因为使用第一个参数进行设置(此处设置为虚拟值)。$1bash -c$0_

  • 请注意,每个文件仅被重命名,即,它保留在其原始目录中

警告

  • 每个具有匹配文件的目录只能包含1 个匹配文件,否则多个文件将按顺序重命名为相同的目标名称 - 实际上,只有最后重命名的文件才能生存。