重命名添加其父文件夹名称的文件
我想用其父文件夹名称重命名文件名,在当前名称之前添加文件夹名称。
例如:
文件夹结构
SOCH NC KT 633-ROYAL BLUE-MULTI | | 1.jpg | | 2.jpg | | 3.jpg
预期结果
SOCH NC KT 633-ROYAL BLUE-MULTI | |_SOCH NC KT 633-ROYAL BLUE-MULTI1.jpg | |_SOCH NC KT 633-ROYAL BLUE-MULTI2.jpg | |_SOCH NC KT 633-ROYAL BLUE-MULTI3.jpg SOCH NC KT 710-BLACK-MULTI
任何人都可以建议如何在.sh文件中完成此操作? 是否有任何实用程序可用于操作?
在一个小的python脚本中, 递归地重命名文件(文件夹和子文件夹):
#!/usr/bin/env python3 import shutil import os import sys dr = sys.argv[1] for root, dirs, files in os.walk(dr): for f in files: shutil.move(root+"/"+f, root+"/"+root.split("/")[-1]+f)
如何使用
- 将脚本复制到空文件中,将其另存为
rename_files.py
-
以目录作为参数运行它:
python3 /path/to/rename_files.py /directory/with/files
注意
一如既往,首先尝试样品!
说明
剧本:
- 走过目录,寻找文件。
-
如果找到文件,它会将路径拆分为带有分隔符“/”的文件,并保留行中的最后一个(即父文件夹名称),以便在文件名称之前粘贴:
root.split("/")[-1]
-
随后,将文件移动到重命名的文件:
shutil.move(root+"/"+f, root+"/"+root.split("/")[-1]+f)
在mv
帮助下只使用shell( bash
):
#!/bin/bash shopt -s globstar ##globstar will let us match files recursively files=( /foo/bar/**/*.jpg ) ##Array containing matched files, mention where to search and what files here for i in "${files[@]}"; do d="${i%/*}" ##Parameter expansion, gets the path upto the parent directory d_="${d##*/}" ##gets the name of parent directory f="${i##*/}" ##gets the file name echo mv "$i" "$d"/"${d_}""$f" ##renaming, remove echo after confirming what will be changed and you are good done
例:
$ shopt -s globstar $ files=( /foo/bar/**/*.jpg ) $ for i in "${files[@]}"; do d="${i%/*}"; d_="${d##*/}"; f="${i##*/}"; echo mv "$i" "$d"/"${d_}""$f"; done mv /foo/bar/KT/633-ROYAL/4.jpg /foo/bar/KT/633-ROYAL/633-ROYAL4.jpg mv /foo/bar/KT/633-ROYAL/5.jpg /foo/bar/KT/633-ROYAL/633-ROYAL5.jpg mv /foo/bar/KT/633-ROYAL/6.jpg /foo/bar/KT/633-ROYAL/633-ROYAL6.jpg mv /foo/bar/KT/633-ROYAL/BLUE-MULTI/1.jpg /foo/bar/KT/633-ROYAL/BLUE-MULTI/BLUE-MULTI1.jpg mv /foo/bar/KT/633-ROYAL/BLUE-MULTI/2.jpg /foo/bar/KT/633-ROYAL/BLUE-MULTI/BLUE-MULTI2.jpg mv /foo/bar/KT/633-ROYAL/BLUE-MULTI/3.jpg /foo/bar/KT/633-ROYAL/BLUE-MULTI/BLUE-MULTI3.jpg
这是一个小例子,说明如何从您要编辑的目录中完成。
$> ls file1.txt file2.txt file3.txt $> pwd /home/xieerqi/testing_dir $> find . -type f -printf "%f\0" | \ > while IFS="" read -d "" filename ; do \ > echo $filename ${PWD##*/}_$filename ; done file2.txt testing_dir_file2.txt file1.txt testing_dir_file1.txt file3.txt testing_dir_file3.txt
用mv
或cp
替换echo
以根据需要进行复制或移动
您可以通过rename
来执行此操作:
rename -n 's/(.*)\//$1\/$1/' */*
需要在要处理的目录正上方的目录中启动此命令。 它首先只列出您要检查的更改,如果您对结果感到满意,则运行它而不使用-n
来执行重命名。
示例运行
$ tree . └── SOCH NC KT 633-ROYAL BLUE-MULTI ├── 1.jpg ├── 2.jpg └── 3.jpg $ rename 's/(.*)\//$1\/$1/' */* $ tree . └── SOCH NC KT 633-ROYAL BLUE-MULTI ├── SOCH NC KT 633-ROYAL BLUE-MULTI1.jpg ├── SOCH NC KT 633-ROYAL BLUE-MULTI2.jpg └── SOCH NC KT 633-ROYAL BLUE-MULTI3.jpg
说明
rename 's/(.*)\//$1\/$1/' */*
-
s/a/b/
–s
byb
-
(.*)\/
– 取出所有内容,直到(不包括)最后一个斜杠,将其保存为组1 并替换它 -
$1\/$1
– 组1(目录名称),斜杠和组1(文件名前缀)
Bash解决方案,从要放置文件名的文件夹执行。 你必须改变workdir
到你的路径
#!/bin/bash shopt -s globstar workdir="/path/to/your/dir" for folder in $workdir/**/*;do if [[ -d "$folder" ]]; then for file in "$folder"/*;do if [[ -f "$file" ]]; then fi="`basename "$file"`" fo="`basename "$folder"`" mv "$file" "$folder/$fo$fi" fi done fi done
它将从您的workdir递归地更改所有目录中的所有文件 。
另一种仅限bash的方法,在需要重命名的文件所在的文件夹中执行:
for f in * ; do mv "$f" "$(basename "$(pwd)")"_"$f" ; done
这也将处理带空格的文件和文件夹名称。