如何基于机器列表与主机名映射批量重命名sosreport压缩文件
批量重命名sosreport压缩包需求
我有一份机器名称与主机名的对应列表/tmp/machine_list.txt,内容示例:
# cat /tmp/machine_list.txt [one]apple machine #1 myserver1 [two]apple machine #2 myserver2 [three]apple machine #3 myserver3
同时存在多个服务器目录(/tmp/sos1、/tmp/sos2、/tmp/sos3等),每个目录下都有一个sosreport压缩包和记录主机名的hostname_map.txt文件,示例:
# ls /tmp/sos1/* sosreport1.tar.gz hostname_map.txt # cat /tmp/sos1/hostname_map.txt myserver1 # ls /tmp/sos2/* sosreport2.tar.gz hostname_map.txt # cat /tmp/sos2/hostname_map.txt myserver2 # ls /tmp/sos3/* sosreport3.tar.gz hostname_map.txt # cat /tmp/sos3/hostname_map.txt myserver3
需要关联/tmp/machine_list.txt和各目录下的hostname_map.txt,将sosreport压缩包重命名为如下格式:
# ls /tmp/sos1/* [one]apple_machine_#1_myserver1_sosreport1.tar.gz # ls /tmp/sos2/* [two]apple_machine_#2_myserver2_sosreport2.tar.gz # ls /tmp/sos3/* [three]apple_machine_#3_myserver3_sosreport3.tar.gz
单个文件重命名可以实现,但如何批量完成该操作?
批量重命名实现方案
可以通过Bash脚本完成批量操作,核心逻辑是先建立主机名到格式化机器描述的映射,再遍历所有sos目录完成匹配和重命名。
方案一:基于Bash关联数组(Bash 4.0+适用)
创建脚本batch_rename_sos.sh:
#!/bin/bash # 构建主机名→格式化机器描述的关联数组 declare -A host_mapping while read -r line; do # 跳过空行和注释行 [[ -z "$line" || "$line" =~ ^# ]] && continue # 提取主机名(最后一个字段) host=$(echo "$line" | awk '{print $NF}') # 提取机器描述并将空格替换为下划线 formatted_desc=$(echo "$line" | awk '{OFS="_"; $NF=""; print $0}' | sed 's/[[:space:]]\+/_/g') host_mapping["$host"]="$formatted_desc" done < /tmp/machine_list.txt # 遍历所有sos开头的目录 for dir in /tmp/sos*; do [[ ! -d "$dir" ]] && continue # 读取当前目录的主机名 target_host=$(cat "$dir/hostname_map.txt" | tr -d '\n') # 检查是否有对应映射 [[ -z "${host_mapping[$target_host]}" ]] && echo "无匹配映射:$dir 中的 $target_host" && continue # 找到目录下的sosreport压缩包 sos_pkg=$(find "$dir" -maxdepth 1 -name "sosreport*.tar.gz") [[ -z "$sos_pkg" ]] && echo "未找到sosreport包:$dir" && continue # 生成新文件名并重命名 new_filename="${host_mapping[$target_host]}_$(basename "$sos_pkg")" mv "$sos_pkg" "$dir/$new_filename" echo "已重命名:$sos_pkg → $dir/$new_filename" done
使用步骤:
- 给脚本添加执行权限:
chmod +x batch_rename_sos.sh - 运行脚本:
./batch_rename_sos.sh
方案二:兼容低版本Bash(无需关联数组)
如果你的Bash版本低于4.0,可使用awk直接匹配映射:
#!/bin/bash # 遍历所有sos开头的目录 for dir in /tmp/sos*; do [[ ! -d "$dir" ]] && continue target_host=$(cat "$dir/hostname_map.txt" | tr -d '\n') # 从machine_list.txt中匹配对应描述并格式化 formatted_desc=$(awk -v host="$target_host" '$NF == host {OFS="_"; $NF=""; print $0}' /tmp/machine_list.txt | sed 's/[[:space:]]\+/_/g') [[ -z "$formatted_desc" ]] && echo "无匹配映射:$dir 中的 $target_host" && continue sos_pkg=$(find "$dir" -maxdepth 1 -name "sosreport*.tar.gz") [[ -z "$sos_pkg" ]] && echo "未找到sosreport包:$dir" && continue new_filename="${formatted_desc}_$(basename "$sos_pkg")" mv "$sos_pkg" "$dir/$new_filename" echo "已重命名:$sos_pkg → $dir/$new_filename" done
内容的提问来源于stack exchange,提问作者hyun.ji
相关产品推荐
相关产品推荐

