我有以下脚本,当我得到一堆需要重命名为包含它们的目录名的文件时,我通常会使用这个脚本。
现在的问题是我需要将文件重命名为两级以上的目录。如何获取祖父目录以使其工作?
使用以下内容我会收到类似此示例的错误:
“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 .
答案 0 :(得分:7)
另一种方法可能是使用
(cd ../../; pwd)
如果在/
,/usr/
或/usr/share/
等任何顶级路径中执行此操作,您将获得/
的有效目录,但是当您深入了解一级,您会看到结果:/usr/share/man/
会返回/usr
,/my/super/deep/path/is/awesome/
会返回/my/super/deep/path
,依此类推。
您也可以将其存储在变量中:
GRANDDADDY="$(cd ../../; pwd)"
然后将其用于脚本的其余部分。
答案 1 :(得分: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"' - {} \;
注意:echo
前置mv
是安全的 - 删除它以执行实际的重命名。
功能
-execdir ..\;
在包含给定匹配文件的特定目录中执行指定的命令,并将{}
扩展为每个文件的文件名。
bash -c
用于执行小型临时脚本:
$(cd ..; basename -- "$PWD")
确定包含该文件的目录的父目录名,该文件是来自文件的 grandparent 路径 perspective。
${old##*.}
是一个Bash parameter expansion,它返回输入文件名的后缀(扩展名)。
注意{}
- 手头的文件名 - 如何作为 2nd 参数传递给命令,以便绑定到$1
,因为{{1使用第一个设置bash -c
(此处设置为虚拟值$0
)。
请注意,每个文件仅重命名,即保留在其原始目录。
<强>买者强>:
答案 2 :(得分:1)
假设文件路径未在/
中结束,如果您使用dirname
则不应该这样做,您可以
Parent = "${filepath%/*}"
Grandparent = "${filepath%/*/*}"
所以做这样的事情
[[ "${filepath%/*/*}" == "" ]] && echo "Path isn't long enough" || echo "${filepath%/*/*}"
如果您使用相对路径(例如find .
),这也可能无效。在这种情况下,您将需要使用
filepath=$(dirname "$f")
filepath=$(readlink -f "$filepath")
而不是
filepath=$(dirname "$f")
此外,您永远不会剥离扩展程序,因此没有理由从文件中获取它,然后再次附加它。
答案 3 :(得分:1)
你不能使用realpath ../../
或readlink -f ../../
吗?请参阅this,readlink(1),realpath(3),canonicalize_file_name(3)和realpath(1)。您可能希望在Debian或Ubuntu上安装realpath
包。可能CentOS有一个相同的包。 (readlink
应始终可用,位于GNU coreutils)