如何使用awk补充分号使文件每行的分号分隔值数量一致?
问题描述
有一个每行分号分隔值数量不同的文件,示例输入如下:
a; 1; 2; 3; 4; b; 11; 22; c; 122; 233; 344; 45; 56; d; 13; e; 144; 25; 36; 47; 58; 69;
希望将其转换为每行分号分隔值数量相同的文件,示例输出如下:
a; 1; 2; 3; 4; ; ; b; 11; 22; ; ; ; ; c; 122; 233; 344; 45; 56; ; d; 13; ; ; ; ; ; e; 144; 25; 36; 47; 58; 69;
作为awk新手,尝试了以下命令但无法批量完成需求:
awk '{if( $4 == ""){print ";"}else{print $4}}' testtest.txt
可行解决方案
方案1:分两步处理(适合新手理解)
第一步:统计最大字段数
先遍历文件,找出所有行中最多有多少个分号分隔的有效字段(示例每行末尾带分号,所以有效字段数为分割后的字段总数减1):
max_fields=$(awk -F';' '{n=NF-1; if(n>max) max=n} END{print max}' testtest.txt)
-F';':指定分号为字段分隔符n=NF-1:计算当前行的有效字段数(去掉末尾空字段)if(n>max) max=n:动态更新最大字段数END{print max}:遍历完成后输出最大字段数
第二步:补全行字段至最大数量
用得到的max_fields补全每行的空字段:
awk -v max="$max_fields" -F';' '{ printf "%s", $1 for(i=2; i<=max+1; i++){ printf ";%s", ($i == "" ? "" : " " substr($i,2)) } print "" }' testtest.txt > output.txt
-v max="$max_fields":把最大字段数传入awk变量- 循环从第2个字段到
max+1:对应补全到max个有效字段 printf ";%s", ...:保持原格式,空字段输出;,非空字段保留原空格格式print "":每行结束后换行
方案2:单命令合并处理
可以把统计和补全合并成一个awk命令,无需单独计算最大值:
awk -F';' ' NR == FNR { n=NF-1 if(n>max) max=n next } { printf "%s", $1 for(i=2; i<=max+1; i++){ printf ";%s", ($i == "" ? "" : " " substr($i,2)) } print "" } ' testtest.txt testtest.txt > output.txt
NR == FNR:第一次遍历文件时仅统计最大字段数next:跳过后续处理,进入下一行- 第二次遍历文件时,按照最大字段数补全行
内容的提问来源于stack exchange,提问作者NightShift
相关产品推荐
相关产品推荐

