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

Awk 用0填充文本文件中的空列,awk,text-files,post-processing,Awk,Text Files,Post Processing,我有一个数据集,我从谷歌电子表格中剪切粘贴到我的文本编辑器中(升华文本2),而这个数据集并不完全符合我的处理需求 以来自电子表格的形式,数据从一行字符串开始,每列一行,然后是多行数据;在数据行中,每列的值为1,或者为空。我不知道当数据来自电子表格时,它是否是以制表符分隔的,但是在粘贴到文本文件中之后,它就不是了。如果行中的最后一个1不在最后一列中,则该行将填充空格,直到但不包括最后一列 我试着用awk做一些事情,但我不知道如何处理空间既是分隔符又是列值这一事实。接下来,我用sed尝试了一些命令,

我有一个数据集,我从谷歌电子表格中剪切粘贴到我的文本编辑器中(升华文本2),而这个数据集并不完全符合我的处理需求

以来自电子表格的形式,数据从一行字符串开始,每列一行,然后是多行数据;在数据行中,每列的值为
1
,或者为空。我不知道当数据来自电子表格时,它是否是以制表符分隔的,但是在粘贴到文本文件中之后,它就不是了。如果行中的最后一个
1
不在最后一列中,则该行将填充空格,直到但不包括最后一列

我试着用
awk
做一些事情,但我不知道如何处理空间既是分隔符又是列值这一事实。接下来,我用
sed
尝试了一些命令,包括用零替换重复的空格,并将管道连接到另一个
sed
,后者用
10
替换
10
,但有时会插入额外的零,我不知道在相应的行中发生了什么

这是一些示例数据(实际文件中有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
处理它


顺便说一句,我看到了,这并不能解决我的问题,因为解决方案是基于这样一个事实,即文件是以制表符分隔的,“空”单元格中没有任何值。重申一下,我的文件是以空格分隔的,空单元格中有空格。

试图解释问题为什么很难解决,这有助于您解决问题。就因为我考虑了这里的解释,我还提出了一个解决方案=)

该解决方案与sed一起工作,基本上分为三个步骤:

  • 将所有空的第一列替换为0:

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

    cat datafile.txt | sed 's/^ /0 /g'
    
    cat datafile.txt | sed 's/^ /0 /g' | sed 's/  $/  0/g'
    
    cat datafile.txt | sed 's/^ /0 /g' | sed 's/  $/  0/g' | sed 's/  / 0/g'
    
    在这里,我必须对正则表达式中的空格数进行一些实验,以便将所有新的零对齐

  • 用0替换所有空的内部列:

    cat datafile.txt | sed 's/^ /0 /g'
    
    cat datafile.txt | sed 's/^ /0 /g' | sed 's/  $/  0/g'
    
    cat datafile.txt | sed 's/^ /0 /g' | sed 's/  $/  0/g' | sed 's/  / 0/g'
    
    在这里,我还尝试将0放在替换正则表达式的第一位或最后一位,以使其正确

  • 当然,完成后,我通过在末尾标记datafile clean.txt将输出重定向到一个文件

    也许有一种更优雅的方法可以做到这一点,所以如果你有一个,请张贴它,即使我个人不需要解决方案了

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

    首先,我们不需要那么多管道;相反,我们在
    sed
    上使用
    -e
    标志:

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

    考虑到具有列标题的第一行没有任何双空格,这一点就可以正常工作。如果是这样的话,你可以用
    tail-n+2 datafile
    读取文件,然后通过管道发送到上面的
    sed
    命令。

    试图解释问题为什么很难解决,这有助于你解决问题。就因为我考虑了这里的解释,我还提出了一个解决方案=)

    该解决方案与sed一起工作,基本上分为三个步骤:

  • 将所有空的第一列替换为0:

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

    cat datafile.txt | sed 's/^ /0 /g'
    
    cat datafile.txt | sed 's/^ /0 /g' | sed 's/  $/  0/g'
    
    cat datafile.txt | sed 's/^ /0 /g' | sed 's/  $/  0/g' | sed 's/  / 0/g'
    
    在这里,我必须对正则表达式中的空格数进行一些实验,以便将所有新的零对齐

  • 用0替换所有空的内部列:

    cat datafile.txt | sed 's/^ /0 /g'
    
    cat datafile.txt | sed 's/^ /0 /g' | sed 's/  $/  0/g'
    
    cat datafile.txt | sed 's/^ /0 /g' | sed 's/  $/  0/g' | sed 's/  / 0/g'
    
    在这里,我还尝试将0放在替换正则表达式的第一位或最后一位,以使其正确

  • 当然,完成后,我通过在末尾标记datafile clean.txt将输出重定向到一个文件

    也许有一种更优雅的方法可以做到这一点,所以如果你有一个,请张贴它,即使我个人不需要解决方案了

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

    首先,我们不需要那么多管道;相反,我们在
    sed
    上使用
    -e
    标志:

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

    考虑到具有列标题的第一行没有任何双空格,这一点就可以正常工作。如果是这样的话,你可以用
    tail-n+2数据文件
    读取文件,然后通过管道发送到上面的
    sed
    命令。

    我的第一次尝试不正常。因此,我的第二次尝试基于修改后的输入,自动确定列数:

    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
    

    我的第一次尝试是不好的。因此,我的第二次尝试基于修改后的输入,自动确定列数:

    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
    

    请,请不要使用
    cat文件| sed…
    !你只是白白浪费资源。使用
    sed…像
    /^…/
    /…$/
    这样的模式是否真的需要
    g
    ?它们只能匹配一次。遗憾的是,没有与
    /$/
    模式匹配的案例。最后一个字符总是一个空格。@TrueY:事实上,在某些情况下,行结束前有多个空格-不幸的是,由于示例行选择不当,我提供的数据中没有显示这一点。我已经更新以反映这一点。仍然不清楚每行添加了多少尾随空格。在第二个输入行中,只有一个尾随空格,但必须添加一个零。但在第三行中也有一个尾随空格,如果以一个结尾。因此,我的解决方案不依赖于尾随空间的数量。请不要使用
    cat file | sed<