Shell脚本如何解析CSV文件数据

wen 实用脚本 1

本文目录导读:

Shell脚本如何解析CSV文件数据

  1. 使用 while read + IFS 基本方案
  2. 使用 awk 处理(推荐)
  3. 处理带引号的CSV(处理引号内逗号)
  4. 完整的CSV解析函数
  5. Python替代方案(更可靠)
  6. 实用示例:提取特定列
  7. 完整示例:处理并转换CSV
  8. 注意事项
  9. 建议

在Shell脚本中解析CSV文件有多种方法,我会介绍几种常见且实用的方式:

使用 while read + IFS 基本方案

#!/bin/bash
# 处理简单的CSV(没有引号内逗号)
while IFS=',' read -r col1 col2 col3 col4; do
    echo "Column1: $col1"
    echo "Column2: $col2"
    echo "Column3: $col3"
    echo "Column4: $col4"
    echo "---"
done < data.csv

使用 awk 处理(推荐)

#!/bin/bash
# 基本awk方案
awk -F',' '{
    for(i=1; i<=NF; i++) {
        printf "Column %d: %s\n", i, $i
    }
    print "---"
}' data.csv

处理带引号的CSV(处理引号内逗号)

#!/bin/bash
# 使用awk处理引号和转义
awk -v FPAT='"[^"]*"|[^,]*' '{
    for(i=1; i<=NF; i++) {
        # 移除引号
        gsub(/^"|"$/, "", $i)
        printf "Column %d: %s\n", i, $i
    }
    print "---"
}' data.csv

完整的CSV解析函数

#!/bin/bash
parse_csv() {
    local file=$1
    while IFS= read -r line; do
        # 使用awk处理引号内逗号
        echo "$line" | awk -v FPAT='"[^"]*"|[^,]*' '{
            for(i=1; i<=NF; i++) {
                gsub(/^"|"$/, "", $i)
                printf "%s", $i
                if(i < NF) printf ","
            }
            print ""
        }' | while IFS=',' read -ra fields; do
            for i in "${!fields[@]}"; do
                echo "Field $((i+1)): ${fields[i]}"
            done
            echo "---"
        done
    done < "$file"
}
# 使用示例
parse_csv "data.csv"

Python替代方案(更可靠)

#!/bin/bash
# 调用Python解析CSV
python3 -c "
import csv
import sys
with open('data.csv', 'r') as file:
    reader = csv.reader(file)
    for row in reader:
        for i, value in enumerate(row, 1):
            print(f'Column {i}: {value}')
        print('---')
"

实用示例:提取特定列

#!/bin/bash
# 提取第2列数据
awk -F',' '{print $2}' data.csv
# 提取多列,跳过表头
awk -F',' 'NR>1 {print $1, $3}' data.csv
# 条件过滤
awk -F',' '$3 > 100 {print $1, $3}' data.csv

完整示例:处理并转换CSV

#!/bin/bash
analyze_csv() {
    local file=$1
    echo "=== CSV 分析报告 ==="
    echo "文件: $file"
    echo ""
    # 读取表头
    header=$(head -1 "$file")
    echo "列名: $header"
    echo ""
    # 统计行数
    total_lines=$(wc -l < "$file")
    data_lines=$((total_lines - 1))
    echo "数据行数: $data_lines"
    echo ""
    # 处理数据(跳过表头)
    tail -n +2 "$file" | while IFS= read -r line; do
        # 这里可以添加你的处理逻辑
        echo "处理: $line"
        # 提取特定字段
        name=$(echo "$line" | cut -d',' -f1)
        value=$(echo "$line" | cut -d',' -f2)
        echo "  Name: $name"
        echo "  Value: $value"
    done
}
# 使用示例
analyze_csv "data.csv"

注意事项

  1. 简单CSV:如果没有引号和转义字符,使用 IFS=',' 即可
  2. 复杂CSV:包含引号内逗号或换行符的CSV,建议使用Python
  3. 性能:大量数据时,awk比bash循环快
  4. 表头处理:注意跳过或正确处理表头行

建议

  • 小型简单CSV:使用 awkwhile read
  • 复杂CSV:使用Python的csv模块
  • 大型CSV:使用专用工具如 csvkit 套件

选择方法取决于你的具体需求和CSV的复杂度,对于生产环境,建议使用专门的CSV解析工具。

抱歉,评论功能暂时关闭!