在 bash 中,如何递归地将每个文件重命名为其父文件夹的名称,同时保留原始扩展名?

时间:2021-04-10 22:53:42

标签: bash freebsd

我有一个很大的文件夹目录,每个文件夹只有一个文件:

directory/folder1/208hasdfasdf.jpg
directory/folder2/f230fsdf.gif
directory/folder3/23fsdbfasf.jpg

I'd like to rename this to:
directory2/folder1/folder1.jpg
directory2/folder2/folder2.gif
directory3/folder3/folder3.jpg

我该怎么做?

2 个答案:

答案 0 :(得分:2)

对于显示的路径和文件名,您可以使用循环和 findsed 的组合进行替换,例如

for f in $(find directory -type f -wholename "*folder*"); do
    mv "$f" $(sed -E 's|^([^/]+)/([^/]+)/([^.]+)[.](.*)$|\1/\2/\2.\4|' <<< "$f")
done

其中 sed -E 's|^([^/]+)/([^/]+)/([^.]+)[.](.*)$|\1/\2/\2.\4| 使用替代分隔符 '|' 而不是 '/' 来简化处理路径名,然后使用 "directory" 分隔并捕获 ^([^/]+),然后带有 "folderX"([^/]+),后跟不带扩展名 ([^.]+) 的文件名,最后是扩展名 (.*)$,通过编号的反向引用 \1、{{ 1}}、\2\3,分别。

然后要形成新文件名,您只需复制 \4 文件夹名代替 \2 文件名,新文件名 \3

示例使用/输出

\1/\2/\2.\4

并用

替换文件名
$ find tmp-david -type f -wholename "*folder*"
tmp-david/folder3/23fsdbfasf.jpg
tmp-david/folder2/f230fsdf.gif
tmp-david/folder1/208hasdfasdf.jpg

结果:

$ for f in $(find tmp-david -type f -wholename "*folder*"); do 
>  mv "$f" $(sed -E 's|^([^/]+)/([^/]+)/([^.]+)[.](.*)$|\1/\2/\2.\4|' <<< "$f")
> done

答案 1 :(得分:1)

假设您使用的是 bash,您可以尝试这样的操作:

find directory/ \( -name '*.gif' -o -name '*.jpg' \) -print | 
while read old; do
  parent=${old%/*}
  base=${parent##*/}
  ext=${old##*.}
  mv $old $parent/$base.$ext
done

如果您要处理包含空格的文件名 需要稍微按摩一下。


在运行此脚本之前:

$ find directory -type f -print
directory/folder2/f230fsdf.gif
directory/folder1/208hasdfasdf.jpg
directory/folder3/23fsdbfasf.jpg

运行此脚本后:

$ find directory -type f -print
directory/folder2/folder2.gif
directory/folder1/folder1.jpg
directory/folder3/folder3.jpg
相关问题