首页 > 解决方案 > 将文件路径的一部分作为前缀添加到文件夹中所有文件的文件名

问题描述

我正在尝试根据上游目录名称重命名文件,但我没有任何 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 脚本中解决这个问题?

标签: 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。一般最好从当前目录进行操作。)

推荐阅读