我正在尝试根据上游目录名称重命名文件,但是我没有任何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脚本中解决这个问题?
答案 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
的原因之一。通常最好是从当前目录进行操作。)