| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- #!/bin/bash
- # 文本文件转C头文件脚本
- # 支持中文和特殊字符
- # 用法: ./text_to_header.sh <输入文件> <输出头文件> <变量名>
- set -e
- # 显示颜色输出
- RED='\033[0;31m'
- GREEN='\033[0;32m'
- YELLOW='\033[1;33m'
- NC='\033[0m' # No Color
- # 显示用法信息
- show_usage() {
- echo -e "${GREEN}用法: $0 <输入文件> <输出头文件> <变量名>${NC}"
- echo -e "${GREEN}示例: $0 input.txt text_data.h my_text${NC}"
- exit 1
- }
- # 检查工具是否安装
- check_tools() {
- local tools=("hexdump" "sed" "awk" "basename" "wc" "file")
- for tool in "${tools[@]}"; do
- if ! command -v "$tool" &> /dev/null; then
- echo -e "${RED}错误: 未找到工具 $tool${NC}"
- exit 1
- fi
- done
- }
- # 检查参数
- if [ $# -ne 3 ]; then
- show_usage
- fi
- INPUT_FILE="$1"
- OUTPUT_FILE="$2"
- VAR_NAME="$3"
- # 检查输入文件
- if [ ! -f "$INPUT_FILE" ]; then
- echo -e "${RED}错误: 输入文件 '$INPUT_FILE' 不存在!${NC}"
- exit 1
- fi
- # 检查文件编码
- FILE_ENCODING=$(file -b --mime-encoding "$INPUT_FILE")
- if [[ "$FILE_ENCODING" != "utf-8" && "$FILE_ENCODING" != "us-ascii" ]]; then
- echo -e "${YELLOW}警告: 文件编码为 $FILE_ENCODING,建议使用UTF-8编码${NC}"
- fi
- # 获取文件信息
- FILENAME=$(basename "$INPUT_FILE")
- FILE_SIZE=$(wc -c < "$INPUT_FILE")
- TEXT_SIZE=$(wc -m < "$INPUT_FILE")
- echo -e "${GREEN}正在处理文件: $INPUT_FILE${NC}"
- echo -e "文件大小: $FILE_SIZE 字节"
- echo -e "文本长度: $TEXT_SIZE 字符"
- echo -e "编码: $FILE_ENCODING"
- # 创建头文件
- create_header() {
- # 创建头文件头部
- cat > "$OUTPUT_FILE" << EOF
- /* 自动生成的文本数据头文件 */
- /* 源文件: $FILENAME */
- /* 文件大小: $FILE_SIZE 字节 */
- /* 生成时间: $(date +"%Y-%m-%d %H:%M:%S") */
- /* 编码: $FILE_ENCODING */
- #ifndef ${VAR_NAME^^}_H
- #define ${VAR_NAME^^}_H
- #include <stddef.h>
- // 文本数据(UTF-8编码)
- const char *${VAR_NAME} =
- EOF
- # 使用hexdump处理文件内容
- echo "正在转换文本内容..."
-
- # 临时文件用于处理转义
- TEMP_FILE=$(mktemp)
-
- # 读取文件并处理转义字符
- while IFS= read -r line || [ -n "$line" ]; do
- # 转义特殊字符
- line=$(printf "%s" "$line" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed 's/^/"/' | sed 's/$/\\n"/')
- echo " $line" >> "$TEMP_FILE"
- done < "$INPUT_FILE"
-
- # 移除最后一行的换行符
- sed -i '$ s/\\n"$/"/' "$TEMP_FILE"
-
- # 将处理后的内容添加到头文件
- cat "$TEMP_FILE" >> "$OUTPUT_FILE"
-
- # 清理临时文件
- rm -f "$TEMP_FILE"
-
- # 完成头文件
- cat >> "$OUTPUT_FILE" << EOF
- ;
- // 文本数据大小(包括null终止符)
- const size_t ${VAR_NAME}_size = $((FILE_SIZE + 1));
- // 文本长度(字符数)
- const size_t ${VAR_NAME}_length = $TEXT_SIZE;
- #endif /* ${VAR_NAME^^}_H */
- EOF
- echo -e "${GREEN}成功生成头文件: $OUTPUT_FILE${NC}"
- }
- # 创建示例C文件
- create_example_c() {
- local example_file="${OUTPUT_FILE%.h}_example.c"
- local base_header=$(basename "$OUTPUT_FILE")
-
- cat > "$example_file" << EOF
- #include <stdio.h>
- #include <string.h>
- #include <locale.h>
- #include "$base_header"
- int main() {
- // 设置locale以支持中文输出
- setlocale(LC_ALL, "zh_CN.UTF-8");
-
- printf("=== 文本数据测试程序 ===\\n");
- printf("文件: %s\\n", "$FILENAME");
- printf("编码: %s\\n", "$FILE_ENCODING");
- printf("\\n");
-
- printf("文本内容:\\n");
- printf("----------------------------------------\\n");
- printf("%s", ${VAR_NAME});
- printf("----------------------------------------\\n");
- printf("\\n");
-
- printf("统计信息:\\n");
- printf("数组大小: %zu 字节\\n", ${VAR_NAME}_size);
- printf("文本长度: %zu 字符\\n", ${VAR_NAME}_length);
- printf("字符串长度: %zu 字节\\n", strlen(${VAR_NAME}));
- printf("\\n");
-
- printf("十六进制查看(前64字节):\\n");
- for (size_t i = 0; i < ${VAR_NAME}_size && i < 64; i++) {
- printf("%02x ", (unsigned char)${VAR_NAME}[i]);
- if ((i + 1) % 16 == 0) printf("\\n");
- }
- printf("\\n");
-
- return 0;
- }
- EOF
- echo -e "${GREEN}创建示例C文件: $example_file${NC}"
- }
- # 创建编译脚本
- create_build_script() {
- local build_script="build_${VAR_NAME}.sh"
- local program_name="${VAR_NAME}_program"
-
- cat > "$build_script" << EOF
- #!/bin/bash
- # 自动编译脚本
- echo -e "\033[0;32m编译程序...\033[0m"
- gcc -Wall -std=c99 -o "$program_name" "${OUTPUT_FILE%.h}_example.c"
- if [ \$? -eq 0 ]; then
- echo -e "\033[0;32m编译成功!\033[0m"
- echo -e "\033[0;33m运行程序: ./$program_name\033[0m"
- else
- echo -e "\033[0;31m编译失败!\033[0m"
- exit 1
- fi
- EOF
- chmod +x "$build_script"
- echo -e "${GREEN}创建编译脚本: $build_script${NC}"
- }
- # 显示文件预览
- show_preview() {
- echo -e "${YELLOW}文件预览(前10行):${NC}"
- head -10 "$INPUT_FILE"
- echo -e "${YELLOW}...${NC}"
- }
- # 主执行流程
- main() {
- check_tools
- show_preview
- create_header
- create_example_c
- create_build_script
-
- echo -e "${GREEN}========================================${NC}"
- echo -e "${GREEN}完成! 接下来可以:${NC}"
- echo -e "1. 查看头文件: ${YELLOW}cat $OUTPUT_FILE${NC}"
- echo -e "2. 编译程序: ${YELLOW}./build_${VAR_NAME}.sh${NC}"
- echo -e "3. 运行程序: ${YELLOW}./${VAR_NAME}_program${NC}"
- echo -e "${GREEN}========================================${NC}"
- }
- # 执行主函数
- main
|