【问题标题】:unix shell scripting to merge multiple lines用于合并多行的 unix shell 脚本
【发布时间】:2014-12-01 10:26:51
【问题描述】:

我有一个文本文件。内容:

game1
game2
game3
game4
/usr/local/games
/usr/local/games
/usr/local/games
/usr/local/games
10
20
30
40

我想要的输出是这样的:

game1   /usr/local/games     10
game2   /usr/local/games     20
game3   /usr/local/games     30
game4   /usr/local/games     40

【问题讨论】:

    标签: linux bash shell unix awk


    【解决方案1】:

    一个使用awk的解决方案:

    $ awk '{i=(NR-1)%n;a[i]=a[i](a[i]?"\t"$0:$0)}END{for(j=0;j<n;j++)print a[j]}' n=4 file
    game1   /usr/local/games        10
    game2   /usr/local/games        20
    game3   /usr/local/games        30
    game4   /usr/local/games        40
    

    您可以更改n 的值以匹配输入的块大小。

    【讨论】:

    • 如果我有超过 3 列怎么办?
    • 您无需担心列数,您只需提供行数,即此示例中的 n=4。在每 4 行末尾创建一个新列 (12/4=3)
    • 噢,谢谢。呃,如果我用以前格式的数据插入mysql数据库,还用shell脚本吗?
    • 它可能在这种情况下找到,但通常避免(a[i]?X:Y),当您想检查之前是否填充了a[i],因为如果a[i] 的值是空字符串,它将表现不佳或计算为数字零。在这种情况下,您可以稳健地使用a[i]=(NR&gt;n?a[i]"\t":"")$0。由于评估的顺序,我不确定a[i]=(i in a?a[i]"\t":"")$0 是否可以保证在所有 awk 中工作(它在 GNU awk 中工作)。
    【解决方案2】:
    awk '
    BEGIN { numRows = 4 }
    {
        rowNr = (NR-1)%numRows+1
        colNr = ++colCnt[rowNr]
        numCols = (colCnt[rowNr] > numCols ? colCnt[rowNr] : numCols)
        val[rowNr,colNr] = $0
    }
    END {
        for (rowNr=1; rowNr<=numRows; rowNr++)
            for (colNr=1; colNr<=numCols; colNr++)
                printf "%s%s", val[rowNr,colNr], (colNr < numCols ? OFS : ORS)
    }
    ' file
    game1 /usr/local/games 10
    game2 /usr/local/games 20
    game3 /usr/local/games 30
    game4 /usr/local/games 40
    

    【讨论】:

      猜你喜欢
      • 2013-08-14
      • 2021-09-06
      • 2012-12-10
      • 2014-12-11
      • 1970-01-01
      • 2014-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多