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

Linux中用Bash正则表达式筛选CSV:保留2010-2011年排除'all countries'

分号分隔CSV筛选方案:保留2010-2011年数据并排除指定Country值

问题背景

处理分号分隔的CSV文件,表头如下:

Unnamed: 0;Unnamed: 0.1;year;country;word;frequency;count;freq_prop_headlines;word_len;freq_rank;hfreq_rank;theme

需求:筛选year列值为2010或2011的行,同时排除country列值为"all countries"的行。

错误分析

你之前尝试的正则^([^;]*;){2}(2010|2011);^all countries.*;无效,原因是:

  • 错误重复使用行首锚点^,年份后的^强制匹配行开头,逻辑矛盾
  • 没有正确表达"country列不等于all countries"的匹配规则

可行解决方案

方案一:组合正向+反向匹配(兼容性好)

用两次grep分别实现筛选年份和排除指定country值,逻辑清晰:

# 先筛选2010/2011年的行,再排除country为all countries的行
grep -E '^([^;]*;){2}(2010|2011);' "$1" | grep -v '^[^;]*;[^;]*;[^;]*;all countries;'
  • 第一个grep:匹配前两个分号后是2010或2011的行(对应year列)
  • 第二个grep -v:反向匹配前三个分号后是"all countries;"的行(对应country列),排除这类行

方案二:单一正则表达式(需GNU grep支持)

使用Perl风格正则的负向预查,一次完成匹配:

grep -P '^([^;]*;){2}(2010|2011);(?!all countries;)' "$1"
  • (?!all countries;)是负向预查,确保year列之后的内容不是"all countries;",即country列不等于该值

保留表头的扩展方案

如果需要保留CSV表头,可先输出表头再处理数据行:

head -n 1 "$1" && grep -E '^([^;]*;){2}(2010|2011);' "$1" | grep -v '^[^;]*;[^;]*;[^;]*;all countries;'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 21:40:20