You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

awk脚本解析总统CSV文件报错求助:按就职年份拆分至对应文件

问题:按总统就职世纪拆分CSV数据到对应文件

需求

解析总统CSV文件,提取总统姓名(第2列),根据就职日期(第4列)的年份,将姓名写入对应世纪的文本文件(如19世纪写入Presidents1900)。

CSV文件片段

28,Woodrow Wilson,http:..en.wikipedia.org.wiki.Woodrow_Wilson,4.03.1913,4.03.1921,Democratic ,WoodrowWilson.gif,thmb_WoodrowWilson.gif,New Jersey
29,Warren G. Harding,http:..en.wikipedia.org.wiki.Warren_G._Harding,4.03.1921,2.8.1923,Republican ,WarrenGHarding.gif,thmb_WarrenGHarding.gif,Ohio 

现有awk脚本

#!/usr/bin/awk -f
 -F, '{
if (substr($4,length($4)-3,2) == "17")
 { print $2 > Presidents1700 }
else if (substr($4,length($4)-3,2) == "18")
{ print $2 > Presidents1800 }
else if (substr($4,length($4)-3,2) == "19")
{ print $2 > Presidents1900 }
else if (substr($4,length($4)-3,2) == "20")
{ print $2 > Presidents2000 }
}' 

运行脚本的Bash函数

SplitFile() {                                                                              
printf "Task 4: Spliting file based on century\n"                                                                                                            
awk -f $AFILE ${custFolder}/${month}/$DFILE                                                                                                                  
}

错误信息

awk: presidentData/10/presidents.csv:47: 46,Joseph Biden,http:..en.wikipedia.org.wiki.Joe_Biden,20.01.2021,Incumbent ,  Democratic   , Joe_Biden.jpg,thmb_Joe_Biden.jpg,Pennsilvania                                                                                                                                                                    awk: presidentData/10/presidents.csv:47:                ^ syntax error                                                                                                      awk: presidentData/10/presidents.csv:47: 46,Joseph Biden,http:..en.wikipedia.org.wiki.Joe_Biden,20.01.2021,Incumbent ,  Democratic   , Joe_Biden.jpg,thmb_Joe_Biden.jpg,Pennsilvania                                                                                                                                                                    awk: presidentData/10/presidents.csv:47:                                                                  ^ syntax error                                                     
awk: presidentData/10/presidents.csv:47: 46,Joseph Biden,http:..en.wikipedia.org.wiki.Joe_Biden,20.01.2021,Incumbent ,  Democratic   , Joe_Biden.jpg,thmb_Joe_Biden.jpg,Pennsilvania                                                                                                                                                                    awk: presidentData/10/presidents.csv:47:                                                                                             ^ syntax error                          
awk: presidentData/10/presidents.csv:47: 46,Joseph Biden,http:..en.wikipedia.org.wiki.Joe_Biden,20.01.2021,Incumbent ,  Democratic   , Joe_Biden.jpg,thmb_Joe_Biden.jpg,Pennsilvania                                                                                                                                                                    awk: presidentData/10/presidents.csv:47:  

问题分析与解决方法

1. 脚本语法错误修正

  • 字段分隔符设置错误:原脚本中-F,前有多余空格,且未正确嵌入脚本。应在BEGIN块中设置FS=",",确保字段按逗号分割。
  • HTML实体引号:脚本中的"是HTML转义字符,需替换为普通双引号",否则awk无法解析条件判断。
  • 文件名未加引号:> Presidents1700中文件名需用引号包裹,否则awk会将其视为变量而非字符串文件名。
  • 日期提取逻辑不可靠:依赖substr($4,length($4)-3,2)提取年份前缀,若日期格式长度变化会失效。改用split拆分日期获取年份更稳定。

2. CSV字段清理

CSV中部分字段包含首尾空格(如Democratic ),会导致字段分割后内容带空格,需先清理字段首尾空白字符。

修正后的awk脚本

#!/usr/bin/awk -f

BEGIN {
    FS = ","  # 设置逗号为字段分隔符
}

{
    # 清理姓名和就职日期字段的首尾空格
    name = $2
    gsub(/^[[:space:]]+|[[:space:]]+$/, "", name)
    inauguration_date = $4
    gsub(/^[[:space:]]+|[[:space:]]+$/, "", inauguration_date)
    
    # 拆分日期获取年份
    split(inauguration_date, date_parts, /\./)
    year = date_parts[3]
    if (year == "") next  # 跳过无有效年份的行
    
    # 生成对应世纪的文件名
    century_prefix = substr(year, 1, 2)
    filename = "Presidents" century_prefix "00"
    
    # 写入文件并记录已打开的文件(避免打开过多文件)
    print name > filename
    files[filename] = 1
}

END {
    # 关闭所有打开的文件
    for (file in files) {
        close(file)
    }
}

3. Bash函数优化

为避免路径含空格时出错,用双引号包裹变量:

SplitFile() {                                                                              
printf "Task 4: Spliting file based on century\n"                                                                                                            
awk -f "$AFILE" "${custFolder}/${month}/$DFILE"
}

内容的提问来源于stack exchange,提问作者9Epicman1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 01:41:05