基于radiosonde.csv的站码-站名映射批量重命名CSV文件的问题咨询
解决批量基于站码映射重命名CSV文件的问题
看起来你的核心需求是把XXX_YYYYMMDD_HH.csv格式的文件名里的站码(XXX)替换成radiosonde.csv里对应的站名,之前的命令和脚本因为语法逻辑问题没完全生效,我来给你梳理问题并提供可靠的解决方案。
原方案的问题分析
- 第一个命令的语法错误:你用
awk生成的bash命令里,${files/" $1 "/" $5 "}包含多余的空格,而且没有正确处理引号匹配——如果radiosonde.csv里的站名或站码有特殊字符(哪怕是隐形的换行符),都会导致bash解析时出现unexpected EOF这类语法错误。另外,sort -r倒序处理CSV会让后面的站码覆盖前面的,而且每个行都生成一个for循环,重复遍历文件,效率低还容易出问题。 - 第二个脚本的逻辑错误:
for file in *00.csv遍历的是目标CSV文件,但$1和$5并没有关联到radiosonde.csv的内容——它们是脚本的位置参数,不是CSV里的CODE和STN_NAME字段,所以这个脚本根本无法拿到映射关系。
可靠的解决方案
方法1:用awk生成正确的重命名命令(单行命令)
这个方法先让awk读取radiosonde.csv,生成对应的mv命令,再交给bash执行,同时处理了可能的文件名特殊字符和不存在文件的情况:
# 如果radiosonde.csv有表头(第一行是CODE,LAT,LON,Elevation,STN_NAME),保留NR>1;没有表头就去掉 awk -F',' 'NR>1 { printf "mv -n \"%s_*.csv\" \"%s_$(echo %s_*.csv | cut -d_ -f2-)\" 2>/dev/null\n", $1, $5, $1 }' radiosonde.csv | bash
关键细节:
-n参数:防止重命名时覆盖已存在的文件(比如两个站码对应同一个站名的情况)- 双引号包裹文件名:避免文件名含空格/特殊字符时出错
cut -d_ -f2-:提取站码之后的后缀部分(比如从36872_20190806_00.csv拿到20190806_00.csv)2>/dev/null:忽略没有找到对应站码文件的错误提示(比如某个站码没有匹配的CSV文件)
方法2:用bash脚本逐行处理(更易调试)
如果需要更清晰的逻辑或者后续扩展,用bash脚本逐行读取radiosonde.csv会更直观:
#!/bin/bash # 跳过表头行(如果radiosonde.csv没有表头,删除下面这行) read -r header # 逐行读取CSV,分割字段 while IFS=',' read -r code lat lon elevation stn_name _; do # 遍历所有以当前站码开头的CSV文件 for file in "${code}"_*.csv; do # 跳过通配符不匹配的情况(即没有找到对应文件) [ -f "$file" ] || continue # 提取站码后的后缀部分 suffix="${file#"${code}_"}" # 构造新文件名 new_file="${stn_name}_${suffix}" # 执行重命名,-n防止覆盖 mv -n "$file" "$new_file" done done < radiosonde.csv
使用步骤:
- 把上面的内容保存为
rename_stations.sh - 赋予执行权限:
chmod +x rename_stations.sh - 运行脚本:
./rename_stations.sh
调试小技巧
在执行重命名之前,先去掉| bash(对应方法1)或者注释掉mv行(对应方法2),查看生成的命令是否符合预期,确认没有语法错误后再执行实际重命名操作。
内容的提问来源于stack exchange,提问作者Ajay
相关产品推荐
相关产品推荐

