将一部分文件路径作为前缀添加到文件夹中所有文件的文件名

时间:2019-05-24 15:01:32

标签: 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脚本中解决这个问题?

1 个答案:

答案 0 :(得分:0)

Shellcheck干净的代码将问题中的描述直接转换为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/}的说明,请参见Removing part of a string (BashFAQ/100 (How do I do string manipulation in bash?))
  • cd ...开头的语句的括号使它们在子shell中运行。这意味着cd(以及可能的exit)不会影响当前的shell。优点是不需要cd回到外部循环的下一次迭代的起始目录。使用cd离开目录后,并非总是可以cd回到目录。
  • exit之后的条件cd(只会退出周围的(创建子shell)括号)是为了防止如果cd失败时试图在错误的目录中移动文件。 Shellcheck抱怨exit是否不存在(这是始终在shell代码上使用Shellcheck的一个好主意之一)。
  • 由于它是在与当前目录不同的目录中执行的,因此echo mv ...的输出可能会造成混淆。 (这就是为什么最好避免在程序中使用cd的原因之一。通常最好是从当前目录进行操作。)