Awk 我使用什么来操作文本文件,从中提取数据,并以表格格式存储输出?
我有一个文本文件,其中包含PERMNO识别的各种股票的每日数据。 因此,文本文件如下所示: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 = 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生成部分非常有用!