如何用sed/awk填充文本中第7列有值行下方的空行
逗号分隔文件的空行填充解决方案
我有一份逗号分隔的文本文件,第7列是关键数据。需求是:将第7列有值的行下方的空行填充为该行内容,但要保留空行中已有的第6列值。之前尝试用sed命令sed -n '/^,/{g;};h;p'时,会错误替换所有空行,求正确的sed或awk实现方案。
输入文件示例
Col1,,Col2,,Col 3,,Session,,Time Mike,,Rg,,Tx,,32658723,,2:00 ,,,,,,,, ,,,,,,23623623,, ,,,,,,,, Joe,,Tx,,Rg,,47235623,,1:00 ,,,,,,,, Peter,,Un,,Xs,,6523,,1:00 ,,,,,,,, Nick,,Xe,,Lk,,67286734,,3:00 ,,,,,,,, ,,,,,,,, ,,,,,,32623,, ,,,,,,,, Bob Li,,Yh,,Xa,,2362,,3:00 ,,,,,,,, ,,,,,,,, ,,,,,,,, ,,,,,,,, ,,,,,,323,, ,,,,,,,, ,,,,,,,, ,,,,,,,, ,,,,,,,, Lin Xu,,Rw,,NB,,1352362,,1:00 ,,,,,,,,
期望输出示例
Col1,,Col2,,Col 3,,Session,,Time Mike,,Rg,,Tx,,32658723,,2:00 Mike,,Rg,,Tx,,32658723,,2:00 Mike,,Rg,,Tx,,23623623,,2:00 Mike,,Rg,,Tx,,23623623,,2:00 Joe,,Tx,,Rg,,47235623,,1:00 Joe,,Tx,,Rg,,47235623,,1:00 Peter,,Un,,Xs,,6523,,1:00 Peter,,Un,,Xs,,6523,,1:00 Nick,,Xe,,Lk,,67286734,,3:00 Nick,,Xe,,Lk,,67286734,,3:00 Nick,,Xe,,Lk,,67286734,,3:00 Nick,,Xe,,Lk,,32623,,3:00 Nick,,Xe,,Lk,,32623,,3:00 Bob Li,,Yh,,Xa,,2362,,3:00 Bob Li,,Yh,,Xa,,2362,,3:00 Bob Li,,Yh,,Xa,,323,,3:00 Bob Li,,Yh,,Xa,,323,,3:00 Bob Li,,Yh,,Xa,,323,,3:00 Bob Li,,Yh,,Xa,,323,,3:00 Bob Li,,Yh,,Xa,,323,,3:00 Lin Xu,,Rw,,NB,,1352362,,1:00 Lin Xu,,Rw,,NB,,1352362,,1:00
awk实现方案(推荐)
awk处理列数据更直观,能精准控制每一列的替换:
BEGIN { FS=OFS="," } $7 != "" { split($0, arr, OFS) print next } { if ($6 != "") arr[6] = $6 line = arr[1] for (i=2; i<=length(arr); i++) { line = line OFS arr[i] } print line }
工作原理
BEGIN { FS=OFS="," }:设置输入和输出的字段分隔符为逗号,确保列对齐。- 当第7列(
$7)非空时,将当前行拆分为数组arr保存为模板,直接打印该行后跳过后续逻辑。 - 处理空行时,检查当前行第6列是否有值,若有则替换模板数组的第6位。
- 把数组重新拼接成完整行并输出。
sed实现方案
sed基于行文本处理,通过正则捕获和保持空间实现需求,逻辑相对复杂:
/[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*/ { h p b } x s/\(\([^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*\),\)[^,]*/\1/ G s/\(\([^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*\),\).*\n\(\([^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*\),\).*/\3\2/ p x
工作原理
- 捕获第7列非空的行,保存到保持空间(
h),打印该行后跳转(b)。 - 对于空行,取出保持空间的模板行,清除其第6列之后的内容。
- 读取当前空行内容,将模板的前5列与空行的第6列(或模板原第6列)拼接,再补上模板的后续列,最后打印结果。
内容的提问来源于stack exchange,提问作者depijp
相关产品推荐
相关产品推荐

