使用Awk将每个字符打印为自己的列?

时间:2010-04-07 21:49:53

标签: awk

我需要重新组织一个大型CSV文件。第一列(当前是一个6位数字)需要拆分,使用逗号作为字段分隔符。

例如,我需要这个:

022250,10:50 AM,274,22,50
022255,11:55 AM,275,22,55

变成了这个:

0,2,2,2,5,0,10:50 AM,274,22,50
0,2,2,2,5,5,11:55 AM,275,22,55

让我知道你的想法!

谢谢!

4 个答案:

答案 0 :(得分:3)

在perl中缩短了很多:

perl -F, -ane '$,=","; print split("",$F[0]), @F[1..$#F]' <file>

既然你不懂perl,快速解释一下。 -F,表示输入字段分隔符是逗号(如awk)。 -a激活自动拆分(进入数组@F),-n隐式地将代码包装在while (<>) { ... }循环中,该循环逐行读取输入。 -e表示下一个参数是要运行的脚本。 $,是输出字段分隔符(它以这种方式设置循环的迭代,但是很好)。 split具有明显的目的,您可以看到数组是如何编入索引/切片的。 print,当列表作为这样的参数时,使用输出字段分隔符并打印所有字段。

在awk中:

awk -F, '{n=split($1,a,""); for (i=1;i<=n;i++) {printf("%s,",a[i])}; for (i=2;i<NF;i++) {printf("%s,",$i)}; print $NF}' <file>

答案 1 :(得分:2)

我认为这可能有效。如果第三个参数是空字符串,则split函数(至少在我运行的版本中)将值拆分为单个字符。

  BEGIN{ FS="," }
  {
     n = split( $1, a, "" );
     for ( i = 1; i <= n; i++ )
        printf("%s,", a[i] );

     sep = "";
     for ( i = 2; i <= NF; i++ )
        {
        printf( "%s%s", sep, $i );
        sep = ",";
        }
     printf("\n");
  }

答案 2 :(得分:2)

这是awk的另一种方式

$ awk -F"," '{gsub(".",",&",$1);sub("^,","",$1)}1' OFS="," file
0,2,2,2,5,0,10:50 AM,274,22,50
0,2,2,2,5,5,11:55 AM,275,22,55

答案 3 :(得分:1)

这是主题的变体。需要注意的一点是它不使用循环就打印剩余的字段。另一个原因是,既然你在第一个字段中循环遍历字符,为什么不使用split()的null-delimiter特性(在某些版本的AWK中可能不存在)呢?

awk -F, 'BEGIN{OFS=","} {len=length($1); for (i=1;i<len; i++) {printf "%s,", substr($1,i,1)}; printf "%s", substr($1,len,1);$1=""; print $0}' filename

作为剧本:

BEGIN {FS = OFS = ","}
{
    len = length($1); 
    for (i=1; i<len; i++)
        {printf "%s,", substr($1, i, 1)}; 
    printf "%s", substr($1, len, 1)
    $1 = "";
    print $0
}