如何用Bash脚本生成含CAD文件信息的XML,解决文件名重复填充问题?
问题描述
我需要用Bash脚本生成特定格式的XML文件,用echo实现基础结构没问题,但要完成以下核心操作:
- 抓取指定目录下所有CAD格式文件,将文件完整路径填入XML的
<File>节点 - 提取每个CAD文件的无路径、无后缀文件名,在XML的多个
<File>节点中重复使用
之前尝试用嵌套数组实现,但生成了多余的行,寻求正确的实现方法。
目标XML示例
<?xml version="1.0" encoding="utf-8"?> <Program version="1.2"> <Input> <Name>Demo</Name> </Input> <Parts> <Part> <Input> <File>C:\opti\O0904\cnhbensonol1\DXF FILES\20038100.SLDPRT</File> <Machine>AutoPOL</Machine> <OnlyUnfolder>true</OnlyUnfolder> <SaveSettings> <NCFile> <Save>true</Save> <Directory>C:\opti\O0904\cnhbensonol1\OUTPUT\NC FILES</Directory> <File>20038100</File> </NCFile> <Graphics> <Save>true</Save> <Directory>C:\opti\O0904\cnhbensonol1\OUTPUT\NC FILES</Directory> <File>20038100</File> </Graphics> <FlatPatternDXF> <Save>true</Save> <Directory>C:\opti\O0904\cnhbensonol1\OUTPUT\DXF FILES</Directory> <DXFSetting>OPTI</DXFSetting> <File>20038100</File> </FlatPatternDXF> <AutoPOLFile> <Save>true</Save> <Directory>C:\opti\O0904\cnhbensonol1\OUTPUT\POLP FILES</Directory> <File>20038100</File> </AutoPOLFile> <ProcessDocumentation> <Save>true</Save> <Directory>C:\opti\O0904\cnhbensonol1\OUTPUT\PDF FILES</Directory> <File>20038100</File> </ProcessDocumentation> </SaveSettings> </Input> </Part> </Parts> </Program>
当前Bash脚本代码
#!/bin/bash set -x # this will grab files from the designated folder and create an xml # Batch and Remote which runs in the background ls "C:/opti/o0904/cnhbensonol1/parts2do/"*.* > tmp #folder with cad files newpath=$(cygpath -w "C:/opti/O0904/cnhbensonol1/parts2do/"*.*) # needs paths with \ rm tmp #it works echo "$newpath" > tmp file_in="tmp" file_out="input.apProgram" # static text formatted header='<?xml version="1.0" encoding="utf-8"?> <Program version="1.2"> <Input> <Name>OPTI</Name> </Input> <Parts>' echo "$header" > $file_out while IFS=$',' read -r -a arry; #this array fills in the cad file for the directory. do echo ' <Part> <Input>' >> $file_out echo ' <File>'${arry[0]}'</File>' >> $file_out echo ' <OnlyUnfolder>true</OnlyUnfolder>' >> $file_out echo ' <SaveSettings> <NCFile> <Save>true</Save> <Directory>C:\opti\o0904\cnhbensonol1\OUTPUT\NC FILES</Directory>' >> $file_out cat tmp | rev | cut -d"\\" -f1 | rev | cut -f1 -d "." > out.txt line=`cat C:/opti/O0904/cnhbensonol1/out.txt` while IFS= read -r line do echo ' <File>'$line'</File> </NCFile> <Graphics> <Save>true</Save> <Directory>C:\opti\o0904\cnhbensonol1\OUTPUT\NC FILES</Directory> <File>'$line'</File> </Graphics> <FlatPatternDXF> <Save>true</Save> <Directory>C:\opti\o0904\cnhbensonol1\OUTPUT\DXF FILES</Directory> <DXFSetting>OPTI</DXFSetting> <File>'$line'</File> </FlatPatternDXF> <AutoPOLFile> <Save>true</Save> <Directory>C:\opti\o0904\cnhbensonol1\OUTPUT\POLP FILES</Directory> <File>'$line'</File> </AutoPOLFile> <ProcessDocumentation> <Save>true</Save> <Directory>C:\opti\o0904\cnhbensonol1\OUTPUT\PDF FILES</Directory> <File>'$line'</File> </ProcessDocumentation> </SaveSettings> </Input>' >> $file_out done < out.txt echo ' </Part>' >> $file_out done < $file_in printf "%s\n" "header" echo ' </Parts> </Program>' >> $file_out rm out.txt rm tmp
输入文件夹

解决方案
原脚本核心问题:
cygpath -w批量处理文件时输出逗号分隔的路径列表,循环读取时会把所有路径当成一行处理,嵌套循环遍历所有文件名导致重复内容- 依赖临时文件传递数据,易出现数据不一致问题
优化后的脚本直接遍历目标目录文件,逐个处理,避免上述问题:
#!/bin/bash set -euo pipefail # 配置参数 CAD_DIR="C:/opti/O0904/cnhbensonol1/parts2do/" OUTPUT_XML="input.apProgram" BASE_OUTPUT_DIR="C:\\opti\\o0904\\cnhbensonol1\\OUTPUT" # 写入XML头部 cat > "$OUTPUT_XML" <<EOF <?xml version="1.0" encoding="utf-8"?> <Program version="1.2"> <Input> <Name>OPTI</Name> </Input> <Parts> EOF # 遍历目录下的所有CAD文件 for cad_file in "$CAD_DIR"*.*; do # 跳过非文件(比如目录) [[ -f "$cad_file" ]] || continue # 转换为Windows格式的完整路径 win_full_path=$(cygpath -w "$cad_file") # 提取无路径、无后缀的文件名 filename=$(basename "$cad_file" | cut -d. -f1) # 写入当前Part的XML内容 cat >> "$OUTPUT_XML" <<EOF <Part> <Input> <File>$win_full_path</File> <Machine>AutoPOL</Machine> <OnlyUnfolder>true</OnlyUnfolder> <SaveSettings> <NCFile> <Save>true</Save> <Directory>$BASE_OUTPUT_DIR\\NC FILES</Directory> <File>$filename</File> </NCFile> <Graphics> <Save>true</Save> <Directory>$BASE_OUTPUT_DIR\\NC FILES</Directory> <File>$filename</File> </Graphics> <FlatPatternDXF> <Save>true</Save> <Directory>$BASE_OUTPUT_DIR\\DXF FILES</Directory> <DXFSetting>OPTI</DXFSetting> <File>$filename</File> </FlatPatternDXF> <AutoPOLFile> <Save>true</Save> <Directory>$BASE_OUTPUT_DIR\\POLP FILES</Directory> <File>$filename</File> </AutoPOLFile> <ProcessDocumentation> <Save>true</Save> <Directory>$BASE_OUTPUT_DIR\\PDF FILES</Directory> <File>$filename</File> </ProcessDocumentation> </SaveSettings> </Input> </Part> EOF done # 写入XML尾部 cat >> "$OUTPUT_XML" <<EOF </Parts> </Program> EOF
关键优化点
- 直接遍历目标目录文件,避免批量路径处理的逗号分隔问题
- 用
cygpath -w逐个转换文件路径,确保每个文件对应正确的Windows路径 - 用
basename+cut提取无后缀文件名,无需临时文件 - 使用
here-document(<<EOF)代替大量echo命令,代码更易维护 - 添加
set -euo pipefail增强脚本健壮性,避免意外错误
内容的提问来源于stack exchange,提问作者fletching
相关产品推荐
相关产品推荐

