用0填充文本文件中的空列

时间:2013-04-20 17:29:26

标签: awk text-files post-processing

我有一个数据集,我从Google电子表格中剪切到我的文本编辑器(Sublime Text 2),数据集并不能完全符合我的处理需求。

以来自电子表格的形式,数据以一行字符串开头,每列一个,然后是一些包含数据的行;在数据行中,每列的值为1或为空。我不知道数据是否来自电子表格时是否分页,但是在文本文件中粘贴后却不是。如果连续的最后一个1不在最后一列中,则该行用空格填充,直到但不包括最后一列。

我尝试用awk做一些事情,但我无法弄清楚如何解决空间是分隔符和列值这一事实。接下来,我使用sed尝试了一些命令,包括用零替换重复的空格并用另一个sed替换10替换为1 0,但后来我有时会得到额外的零插入,我不知道在相应的行中发生了什么。

这是一些示例数据(真实文件中有13列)。我已添加$作为该行上最后一个字符后面的字符,因此您可以看到这些行被填充的距离。

"1" "2" "3" "4"                           "1" "2" "3" "4"
  1 1 $                                   0 1 1 0
1     1 $                                 1 0 0 1
  1   $                                   0 1 0 0
1 1   1 $                                 1 1 0 1

我想最终得到类似的东西(然后我不关心线的终点),所以我可以用awk处理它。

顺便说一句,我已经看到了this question,这并没有解决我的问题,因为解决方案是基于文件以制表符分隔的事实,没有在“空”单元格中的价值。重申一下,我的文件是以空格分隔的,空单元格中有空格。

3 个答案:

答案 0 :(得分:0)

试图解释为什么问题困难有利于你解决问题的机会。仅仅因为我在这里考虑了解释,我也想出了一个解决方案=)

该解决方案适用于sed,基本上分为三个步骤:

  1. 将所有空的第一个列替换为0:

    cat datafile.txt | sed 's/^ /0 /g'
    
  2. 将所有空最后列替换为0:

    cat datafile.txt | sed 's/^ /0 /g' | sed 's/  $/  0/g'
    

    在这里,我不得不尝试使用正则表达式中的空格数量来对齐所有新的零。

  3. 将所有空内部列替换为0:

    cat datafile.txt | sed 's/^ /0 /g' | sed 's/  $/  0/g' | sed 's/  / 0/g'
    

    在这里,我还尝试将0或者最后一个放在替换正则表达式中以使其正确。

  4. 当然,完成此操作后,我会通过在最后> datafile-clean.txt处标记来将输出重定向到文件。

    这可能是一种更优雅的方式,所以如果你有一个,请发布,即使我个人不再需要解决方案。

    更新:如评论所示,此解决方案可以进行很多改进。我将把原始解决方案留在这里,因为我认为它更清楚它的作用,以及它的顺序,但是这应该可以用来代替。

    首先,我们不需要这么多管道;相反,我们使用-e上的sed标记:

    sed -e 's/^  /0 /' -e 's/  $/ 0/' -e 's/  / 0/g' datafile.txt
    

    这是按原样工作的,因为带有列标题的第一行没有任何双空格。如果是,则可以使用tail -n +2 datafile读取文件,并使用上述sed命令。

答案 1 :(得分:0)

我的第一次尝试不行。所以我的第二次 第三次第四次尝试根据修改后的输入自动确定列数:

awk 'NR==1{for(;N<NF;++N)sp=" 0"sp}NR>1{$0=" "$0;sub(" +$","");gsub("  "," 0");$0=substr($0sp,2,2*N-1)}1'<<EOT
"1" "2" "3" "4"
  1 1 
1     1 
  1   
1 1   1 
EOT

第一个空格是偶数,其间是奇数,所以我在开头添加了一个空格,让两个案例都使用相同的gsub。目前尚不清楚有多少尾随空格,因此脚本只是扼杀它们。它包含0个字段时间的数量。 Substr从2开始剪切添加的前导空格,并持续到(number of fields)*2-1个字符以剪切尾随空格。

输出:

"1" "2" "3" "4"
0 1 1 0
1 0 0 1
0 1 0 0
1 1 0 1

答案 2 :(得分:0)

sed 's/ /0/g;s/10/1 /g;s/00/0 /g;s/$/0 /' datafile.txt | cut -c 1-7