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

如何使用Bash处理CSV文件 合并交替行生成分号分隔的成对记录

跨行配对转分号分隔CSV的实现方案

你的需求本质是按「用户名行+日期行」的固定两两配对规则做行合并,以下是几种可直接运行的实现,覆盖你之前尝试的read命令方向:

方案1:Bash 原生read实现(匹配你最初的尝试方向)

逐行读取文件内容,遇到uid:开头的行暂存用户名,读到紧随其后的日期行就拼接输出,逻辑完全贴合配对规则,不会出现错位:

#!/bin/bash
# 初始化输出文件
> newcsv.csv
username=""
while IFS= read -r raw_line; do
  # 去除每行首尾的空白字符,兼容原文件行尾多余空格
  line=$(echo "$raw_line" | xargs)
  if [[ $line == uid:* ]]; then
    # 截掉uid:前缀,提取用户名
    username=${line#uid:}
  elif [[ -n $username && $line =~ ^[0-9]{8}$ ]]; then
    # 已暂存用户名、且当前行为8位日期时,拼接写入结果
    echo "$username;$line" >> newcsv.csv
    # 清空暂存的用户名,避免后续行错位
    username=""
  fi
done < csv.csv

给脚本加执行权限后直接运行即可生成目标文件。

方案2:Awk 一行命令(高效简洁,适合快速处理)

Awk天生适合流文本的跨行处理,不需要写复杂循环,一行命令就能完成转换:

awk '
  { gsub(/^[[:space:]]+|[[:space:]]+$/,"",$0) }
  /^uid:/ { user = substr($0, 5); next }
  { print user ";" $0 }
' csv.csv > newcsv.csv

逻辑拆解:

  • 第一步先统一去掉每行首尾的空白,避免多余空格干扰匹配
  • 匹配到uid:开头的行时,截取uid:之后的内容存为用户名变量,跳过当前行后续处理
  • 其余行(即日期行)直接用暂存的用户名和当前日期拼接输出

方案3:Sed 流编辑实现(无额外变量依赖)

通过Sed的N命令直接把相邻两行读入同一模式空间做正则替换,不需要暂存变量:

sed -E '
  N
  s/^[[:space:]]*uid:([^[:space:]]+)[[:space:]]*\n[[:space:]]*([0-9]+)[[:space:]]*$/\1;\2/
' csv.csv > newcsv.csv

逻辑拆解:

  • N:读取下一行追加到当前行后,两行用换行符分隔
  • 正则匹配uid:用户名 + 换行 + 日期的结构,直接替换为用户名;日期的目标格式,同时自动过滤所有多余空白

避坑提示:如果你的csv.csv是Windows下生成的,先执行dos2unix csv.csv转换换行符格式,避免read/awk/sed读取时出现行尾\r导致的格式错误。


内容的提问来源于stack exchange,提问作者vinc.slg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 21:12:41