Awk 我使用什么来操作文本文件,从中提取数据,并以表格格式存储输出?

Awk 我使用什么来操作文本文件,从中提取数据,并以表格格式存储输出?,awk,sed,sh,Awk,Sed,Sh,我有一个文本文件,其中包含PERMNO识别的各种股票的每日数据。 因此,文本文件如下所示: PERMNO = 1234 PERMNO = 2134 Market data: Date | Price | Return | Volume -------------------------------- 2019-01-01| 120 | 100 | 100 PERMNO = 3456 Market data: Date | Price | Return

我有一个文本文件,其中包含PERMNO识别的各种股票的每日数据。 因此,文本文件如下所示:

PERMNO = 1234

PERMNO = 2134

Market data:

    Date | Price | Return | Volume
    --------------------------------
    2019-01-01| 120 | 100 | 100

PERMNO = 3456

Market data:

    Date | Price | Return | Volume
    --------------------------------
    2019-01-01| 200 | 150 | 130
Market data:

    Date | Price | Return | Volume | PERMNO
    -----------------------------------------
    2019-01-01| 120 | 100 | 100 | 1234,2134
    2019-01-01| 200 | 150 | 130 | 3456
$ ./marketdata.sh MarketData.txt
PERMNO = 1234
PERMNO = 2134
Market data:
Date     Price   Return          Volume PERMNO
--------------------------------
2019-01-01       120     100     100    1234,2134
PERMNO = 3456
Market data:
Date     Price   Return          Volume PERMNO
--------------------------------
2019-01-01       200     150     130    3456
我想做的是提取所有的PERMNO,直到市场数据并将其合并,通过在其余数据旁边添加一个新列PERMNO,将其与其余的市场数据一起显示。所以它应该是这样的:

PERMNO = 1234

PERMNO = 2134

Market data:

    Date | Price | Return | Volume
    --------------------------------
    2019-01-01| 120 | 100 | 100

PERMNO = 3456

Market data:

    Date | Price | Return | Volume
    --------------------------------
    2019-01-01| 200 | 150 | 130
Market data:

    Date | Price | Return | Volume | PERMNO
    -----------------------------------------
    2019-01-01| 120 | 100 | 100 | 1234,2134
    2019-01-01| 200 | 150 | 130 | 3456
$ ./marketdata.sh MarketData.txt
PERMNO = 1234
PERMNO = 2134
Market data:
Date     Price   Return          Volume PERMNO
--------------------------------
2019-01-01       120     100     100    1234,2134
PERMNO = 3456
Market data:
Date     Price   Return          Volume PERMNO
--------------------------------
2019-01-01       200     150     130    3456

我正试着用awk来做这个。我可以用这个来提取PERMNO,但我无法通过添加新的专栏来将它和其他市场数据结合起来。任何类似sed的awk替代方案也可以。但是我对shell脚本还是新手,所以我不知道它们的全部功能。有人能建议我如何处理这个问题吗?

这似乎给出了想要的输出(使用gawk 4.14):

$ ./marketdata.sh MarketData.txt
PERMNO = 1234
PERMNO = 2134
Market data:
Date     Price   Return          Volume PERMNO
--------------------------------
2019-01-01       120     100     100    1234,2134
PERMNO = 3456
Market data:
Date     Price   Return          Volume PERMNO
--------------------------------
2019-01-01       200     150     130    3456
输出:

$ ./marketdata.sh MarketData.txt
PERMNO = 1234
PERMNO = 2134
Market data:
Date     Price   Return          Volume PERMNO
--------------------------------
2019-01-01       120     100     100    1234,2134
PERMNO = 3456
Market data:
Date     Price   Return          Volume PERMNO
--------------------------------
2019-01-01       200     150     130    3456
你可以这样做:

$ ./marketdata.sh MarketData.txt
PERMNO = 1234
PERMNO = 2134
Market data:
Date     Price   Return          Volume PERMNO
--------------------------------
2019-01-01       120     100     100    1234,2134
PERMNO = 3456
Market data:
Date     Price   Return          Volume PERMNO
--------------------------------
2019-01-01       200     150     130    3456
BEGIN {FS=" = " ; H="Market data:\n\n    Date | Price | Return | Volume | PERMNO" ; print H}
/PERMNO/ {PNO = PNO "," $2 "," }
/2[0-9]{3}-/ { gsub(",,+",",",PNO) ; gsub("^,|,$","",PNO) ; print $0 " | " PNO ; PNO = ""; next}
  • 第一行设置
    PERMNO
    行的字段分隔符,并打印标题
  • 第二行保存(并附加)
    PERMNO
    id(仅在与
    PERMNO
    匹配的行上)
  • 第三行在该行与类似年份的模式匹配时执行(这可能会被扩展/修改),清除
    PNO
    变量(无前导、结尾或重复逗号),然后使用附加的
    PNO
    值打印整行

  • 它。

    您可以通过以下方式获得您想要的:

    $ ./marketdata.sh MarketData.txt
    PERMNO = 1234
    PERMNO = 2134
    Market data:
    Date     Price   Return          Volume PERMNO
    --------------------------------
    2019-01-01       120     100     100    1234,2134
    PERMNO = 3456
    Market data:
    Date     Price   Return          Volume PERMNO
    --------------------------------
    2019-01-01       200     150     130    3456
    
    $ cat tst.awk
    BEGIN { OFS=" | " }
    
    /^PERMNO/ {
        permnos = ( permnos == "" ? "" : permnos ",") $NF
    }
    
    /^ +[[:alpha:]]/ && !doneHdr++ {
        indent = text = $0
        sub(/[^ ].*/,"",indent)
        sub(/^ +/,"",text)
        hdr = text OFS "PERMNO"
        sep = sprintf("%*s",length(hdr)+2,"")
        gsub(/ /,"-",sep)
        print "Market data:" ORS ORS indent hdr ORS indent sep
    }
    
    /^ +[0-9]/ {
        print $0, permnos
        permnos = ""
    }
    
    $ awk -f tst.awk file
    Market data:
    
        Date | Price | Return | Volume | PERMNO
        -----------------------------------------
        2019-01-01| 120 | 100 | 100 | 1234,2134
        2019-01-01| 200 | 150 | 130 | 3456
    
    但我强烈建议您只生成CSV,以便于进一步分析/操作:

    $ ./marketdata.sh MarketData.txt
    PERMNO = 1234
    PERMNO = 2134
    Market data:
    Date     Price   Return          Volume PERMNO
    --------------------------------
    2019-01-01       120     100     100    1234,2134
    PERMNO = 3456
    Market data:
    Date     Price   Return          Volume PERMNO
    --------------------------------
    2019-01-01       200     150     130    3456
    
    $ cat tst.awk
    BEGIN { FS="[ |]+"; OFS="," }
    
    /^PERMNO/ {
        permnos = ( permnos == "" ? "" : permnos " ") $NF
    }
    
    sub(/^ +/,"") {
        $1 = $1
        if ( /^[[:alpha:]]/ && !doneHdr++ ) {
            print $0, "PERMNO"
        }
        else if ( /^[0-9]/ ) {
            print $0, permnos
            permnos = ""
        }
    }
    
    $ awk -f tst.awk file
    Date,Price,Return,Volume,PERMNO
    2019-01-01,120,100,100,1234 2134
    2019-01-01,200,150,130,3456
    
    如果您喜欢使用各种工具,例如使用
    ,则始终可以从中生成表格格式:

    $ ./marketdata.sh MarketData.txt
    PERMNO = 1234
    PERMNO = 2134
    Market data:
    Date     Price   Return          Volume PERMNO
    --------------------------------
    2019-01-01       120     100     100    1234,2134
    PERMNO = 3456
    Market data:
    Date     Price   Return          Volume PERMNO
    --------------------------------
    2019-01-01       200     150     130    3456
    
    $ awk -f tst.awk file | column -s, -o' | ' -t
    Date       | Price | Return | Volume | PERMNO
    2019-01-01 | 120   | 100    | 100    | 1234 2134
    2019-01-01 | 200   | 150    | 130    | 3456
    
    如果您喜欢标题下的那行下划线:

    $ ./marketdata.sh MarketData.txt
    PERMNO = 1234
    PERMNO = 2134
    Market data:
    Date     Price   Return          Volume PERMNO
    --------------------------------
    2019-01-01       120     100     100    1234,2134
    PERMNO = 3456
    Market data:
    Date     Price   Return          Volume PERMNO
    --------------------------------
    2019-01-01       200     150     130    3456
    
    $ awk -f tst.awk file | column -s, -o' | ' -t | awk '1;NR==1{gsub(/./,"-");print}'
    Date       | Price | Return | Volume | PERMNO
    ---------------------------------------------
    2019-01-01 | 120   | 100    | 100    | 1234 2134
    2019-01-01 | 200   | 150    | 130    | 3456
    

    你能提供更多关于你的脚本应该如何知道PERMNO=1234的市场数据的信息吗?只是因为没有提供数据,才应该使用下一个PERMNO的数据吗?在每个PERMNO列表之后,都有一行“市场数据”,然后这些PERMNO的数据从下一行开始。在这之后,再次列出PERMNO,然后是一行“市场数据”,然后是数据等等。因此,脚本应该识别,如果$1=='Market',那么上面对应于PERMNO的表格数据应该从下一条记录开始。不知怎的,当我运行它时,它只打印它遇到的最后一条PERMNO,而不是所有的PERMNO组合,用“,”分隔。你能解释一下下面这行做什么吗="" ? p“,”$3:$3
    a?b:c
    if(a){b}else{c}
    的一个简短符号,如果它只打印最后一个PERMNO,它可能与行尾有关,在Linux/windows/mac下不同,您使用什么操作系统?gawk更喜欢Linux,而不是现在正在运行的Windows。我在编写代码时输入了一个错误。谢谢我试着运行这个。它不打印PNO的任何值。这很奇怪。正如你所看到的,在ideone.com上,它运行得非常完美。那么输出是什么呢?您使用的是什么版本的OS/AWK?哦,我明白了,你已经有了一个公认的答案。谢谢。csv生成部分非常有用!