如何用Bash脚本(Awk/Sed/Grep等)拆分动态CSV文件为3个文件
解决方案:用Awk拆分动态制表符分隔CSV文件
以下是基于Awk的Bash脚本,可实现将FileA.csv按指定表头拆分为三个独立文件:
完整拆分脚本(每次生成最新完整文件)
#!/bin/bash # 定义输入输出文件路径 INPUT="FileA.csv" ABC_OUT="ABC.csv" DEF_OUT="DEF.csv" GHI_OUT="GHI.csv" # 清空输出文件,确保每次生成完整干净的内容 > "$ABC_OUT" > "$DEF_OUT" > "$GHI_OUT" # Awk核心逻辑 awk ' # 初始化当前输出目标 BEGIN { target = "" } # 匹配HEADER 1,切换输出到ABC.csv $0 == "HEADER 1" { target = "'"$ABC_OUT"'" print > target next } # 匹配HEADER 2,切换输出到DEF.csv $0 == "HEADER 2" { target = "'"$DEF_OUT"'" print > target next } # 匹配HEADER 3,切换输出到GHI.csv $0 == "HEADER 3" { target = "'"$GHI_OUT"'" print > target next } # 将当前行写入对应的目标文件 target != "" { print > target } ' "$INPUT"
脚本说明
- 文件初始化:先清空三个输出文件,避免重复写入表头或旧数据。如果需要保留历史增量内容,可删除清空文件的三行,但会导致表头重复,不推荐。
- 表头匹配逻辑:通过整行匹配表头字符串,自动切换对应的输出文件。
- 内容写入:非表头行根据当前的输出目标,自动写入对应文件。
增量处理优化(仅处理新增内容)
由于HEADER 3及以下内容固定,第一次拆分后无需重复生成GHI.csv。若只需处理FileA.csv新增的HEADER 1/HEADER 2数据,可做如下调整:
- 第一次运行上述完整脚本生成三个文件。
- 后续运行时,记录上次处理到的行数,仅处理新增行:
#!/bin/bash INPUT="FileA.csv" ABC_OUT="ABC.csv" DEF_OUT="DEF.csv" LAST_LINE_FILE=".last_line" # 获取上次处理的行数,默认从第一行开始 last_line=$(cat "$LAST_LINE_FILE" 2>/dev/null || echo 0) total_lines=$(wc -l < "$INPUT") # 仅当有新增行时处理 if [ "$total_lines" -gt "$last_line" ]; then awk -v start="$((last_line + 1))" ' NR >= start { if ($0 == "HEADER 1") { target = "'"$ABC_OUT"'" } else if ($0 == "HEADER 2") { target = "'"$DEF_OUT"'" } else if ($0 == "HEADER 3") { exit } # 跳过HEADER3及以下的固定内容 else if (target != "") { print >> target } } ' "$INPUT" # 更新上次处理的行数 echo "$total_lines" > "$LAST_LINE_FILE" fi
注意事项
- 如果表头字符串包含特殊字符(如引号、正则元字符),需在Awk的匹配条件中做转义处理。
- 确保脚本有读写输入输出文件的权限。
- 若
FileA.csv的表头行存在空格或大小写差异,需调整匹配字符串严格对应。
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

