我想用其父文件夹名称重命名文件名,添加当前名称之前的文件夹名称。
例如:
文件夹结构
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 文件中完成此操作吗?是否有可用的实用程序来执行此操作?
答案1
在一个小的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)
答案2
您可以使用以下方式执行此操作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
替代a
为b
(.*)\/
– 将所有内容(除了)最后一个斜线保存为第 1 组 并将其替换为$1\/$1
– 组 1(目录名),斜线,然后再次组 1(文件名前缀)
答案3
仅使用 shell ( bash
) 并借助以下帮助mv
:
#!/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
答案4
这是一个关于如何从您想要编辑的目录中完成此操作的小示例。
$> 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
根据需要替换echo
为mv
或进行复制或移动cp