bash - 将文件路径的一部分作为前缀添加到文件夹中所有文件的文件名
问题描述
我正在尝试根据上游目录名称重命名文件,但我没有任何 bash 脚本经验。
假设我有一个目录,其中包含数千个名为“k99_xxx_properties”的目录,并且在每个 k99 目录中都有一个 Alignments 目录,在 Alignments 目录中有名为 sample1、sample2、sample3 等的文件。我想要做的是通过添加上游目录的“k99_xxx”部分作为前缀(“k99_xxx_sample1”)来重命名示例文件。
我知道我需要做的就是遍历所有 k99_xxx_properties 目录,将目录名称的 k99_xxx 部分保存为变量,然后导航到每个 k99_xxx,cd 到 Alignments,然后遍历 Alignments 中的每个文件以添加 k99_xxx 作为前缀示例文件名。
我将如何在 bash 脚本中解决这个问题?
解决方案
此Shellcheck -clean 代码将问题中的描述直接翻译为 Bash:
#! /bin/bash -p
shopt -s nullglob # Globs that match nothing expand to nothing
# Loop through all k99_xxx_properties directories
for k99dir in k99_*_properties/ ; do
# Save the k99_xxx portion of the directory name as a variable
k999_xxx=${k99dir%_properties/}
# (Skip the directory if it doesn't have an 'Alignments' subdirectory)
[[ -d ${k99dir}Alignments ]] || continue
# navigate into each k99_xxx, cd into Alignments
(
cd -- "${k99dir}Alignments" || exit
# loop through every file in Alignments to add k99_xxx
# as a prefix for the sample filenames.
for sf in sample* ; do
echo mv -- "$sf" "${k999_xxx}_${sf}"
mv -- "$sf" "${k999_xxx}_${sf}"
done
)
done
shopt -s nullglob
是为了防止代码尝试处理虚假的“k99_*_properties”目录或“sample*”文件(如果它在不存在的地方运行)。- 有关. _ _
${k99dir%_properties/}
- 开始的语句周围的括号
cd ...
导致它们在子shell中运行。这意味着cd
(和可能的exit
)不会影响当前的 shell。优点是无需cd
回到起始目录进行外循环的下一次迭代。使用离开后并不总是可以cd
返回目录。cd
- 条件
exit
之后cd
(仅退出周围的(创建子shell)括号)是为了防止在失败时尝试在错误的目录中移动文件cd
。 如果不存在, Shellcheck 会抱怨(这就是为什么总是在 shell 代码上使用Shellcheckexit
是个好主意的原因之一)。 - 由于它是在与当前目录不同的目录中执行的,因此 的输出
echo mv ...
可能会令人困惑。(这是最好避免在程序中使用的原因之一cd
。一般最好从当前目录进行操作。)
推荐阅读
- c++ - 为什么 memset 可以用零初始化 C++ 中的 2D 数组,但在像这样声明 `array[n][k+1]={0}` 时无法设置?
- visual-studio-code - 使用 VS Code Dev Container 仅构建所需的 docker-compose.yaml 服务
- pandas - 数据框行改组
- git - Git 只合并一些提交
- python - 在特定点重复 python 脚本
- php - 注意:尝试在第 83 行访问 bool 类型值的数组偏移量
- javascript - PHP 调用 Javscript 函数时出现“未捕获的 ReferenceError:未定义 gotoLogIn”
- mysql - MySQL 在至少 X 个项目上加入数据集
- c# - ASP.NET Entity Framework 加载嵌套的相关数据
- c++ - 如何检查字符串向量中字符的所有邻居