【问题标题】:Convert single column file into multiple columns将单列文件转换为多列
【发布时间】:2014-05-25 03:28:36
【问题描述】:

基本上,我想将一个列文件转换为由行数指定的多个列文件。

我不想重新发明轮子。在编写自定义脚本之前,我想确定是否有 unix 命令/或标准方式来执行此操作。

例如,假设我有以下文件:

$cat input.txt
tom
jack
kim
bart
foo
bar

我想把它变成 3 行文件

$ cat input.txt | my_script --every=3 --delimiter=tab
tom bart
jack foo
kim bar

或具有不同分隔符的 2 行文件:

$ cat input.txt | my_script --every=2 --delimiter=,
tom,kim,foo
jack,bart,bar

【问题讨论】:

    标签: bash unix command-line multiple-columns


    【解决方案1】:

    我尝试了上面提供的几种解决方案,包括 paste - -xargs -n2,但这些都不能满足 OP 要求,即 列表的一半在一列,另一半在另一列强>。我没有尝试awk 解决方案,因为它看起来很笨重、冗长,而且没有太多解释代码在做什么。

    经过一番挖掘,我发现这给出了一个使用pr 的简短而优雅的解决方案:

    echo "tom
    jack
    kim
    bart
    foo
    bar" > my_file
    
    cat my_file | pr -2 -t -s
    

    返回:

    tom bart
    jack    foo
    kim bar
    

    如果你想用逗号分隔:

    cat my_file | pr -2 -t -s,
    

    返回:

    tom,bart
    jack,foo
    kim,bar
    

    来自pr 联机帮助页:

    -s char
          Separate text columns by the single character char instead of by the appropriate number of <space>s (default for char is the <tab> character).
    
    -t    Print neither the five-line identifying header nor the five-line trailer usually supplied for each page.  Quit printing after the last line of each file without
          spacing to the end of the page.
    

    【讨论】:

      【解决方案2】:

      您可以在 UNIX 中使用paste 命令将文件转换为多列。默认情况下,制表符是分隔符。要更改分隔符,请使用-d 选项

      命令:将一列文件转换为两列

      paste - - < input.txt
      

      输出:

      tom  bart 
      jack foo 
      kim  bar
      

      命令:将一列文件转换成两列,以,为分隔符

      paste - - -d, < input.txt
      

      输出:

      tom,bart 
      jack,foo 
      kim,bar
      

      【讨论】:

        【解决方案3】:

        使用xargs怎么样?

        每行两条记录:

        $ xargs -n2 < file
        tom jack
        kim bart
        foo bar
        

        每行三个记录:

        $ xargs -n3 < file
        tom jack kim
        bart foo bar
        

        【讨论】:

          【解决方案4】:

          首先,您可以使用 sed 获取正确的数据,例如

          $ sed -n '1~2p' input
          tom
          kim
          foo
          
          $ sed -n '2~2p' input
          jack
          bart
          bar
          

          那么有很多方法可以将一列转换为一行。仅举几例:

          tr '\n' ' ' < file
          
          awk -vORS=' ' 1 file
          
          paste -sd" " file
          

          【讨论】:

          • 这其实不是我想要的。对于两列示例,我希望 tom、jack、kim 在同一列中
          【解决方案5】:

          awk

           awk -v row=2 '{A[(NR-1)%row]=A[(NR-1)%row]$0" ";next}END{for(i in A)print A[i]}' file
          

          输出:

          tom  bart 
          jack foo 
          kim  bar 
          

          在此处指定raw 变量中所需的行数。例如:row=3 三行。

          如果您只想打破特定行中的列,请尝试这样

          cat file | xargs -n2

          这里 2 每行包含 2 列,你可以使用你想要的。

          【讨论】:

          • Op 想要 tom bart;jack foo;kim bartom jack;kim bart;foo bar
          【解决方案6】:

          使用 awk

          awk '{a[(NR-1)%n]=a[(NR-1)%n]==""?$1:a[(NR-1)%n] OFS $1}END{for (i=0;i<n;i++) print a[i]}' n=3 OFS="\t" file
          
          tom     bart
          jack    foo
          kim     bar
          
          
          awk '{a[(NR-1)%n]=a[(NR-1)%n]==""?$1:a[(NR-1)%n] OFS $1}END{for (i=0;i<n;i++) print a[i]}' n=2 OFS="," file
          
          tom,kim,foo
          jack,bart,bar
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多