我有一个数据,没有按照适当的字段分隔符格式化(这是awk擅长)。但是,我所知道的是,数据是固定的宽度。
NODE S1 S2 S3 SINT SEQV
1 0.14919 -0.58396E-001-0.71230 0.86149 0.77873
2 0.56037E-001 0.23261E-002-0.37154 0.42757 0.40341
3 0.52036E-001 0.19762E-001-0.27222 0.32426 0.30939
4 0.59765E-001 0.22059E-001-0.24529 0.30505 0.28806
5 0.70704E-001-0.51976E-002-0.13862 0.20932 0.18354
6 0.11906 0.44607E-001-0.17493 0.29399 0.26474
7 0.25540 0.95993E-002-0.43110 0.68650 0.60246
8 0.52246E-001-0.47008E-001-0.35167 0.40391 0.36456
9 0.32215E-001-0.62291E-001-0.28800 0.32021 0.28497
10 0.28072E-001-0.68269E-001-0.28304 0.31111 0.27586
11 0.25990E-001-0.78663E-001-0.28626 0.31225 0.27527
12 0.26657E-001-0.79217E-001-0.29507 0.32173 0.28400
预期输出是这样的(其他列中的数字可以具有类似于S2的格式,在数据的其他部分中):
NODE S1 S2 S3 SINT SEQV
1 0.14919 -0.58396E-001 -0.71230 0.86149 0.77873
2 0.56037E-001 0.23261E-002 -0.37154 0.42757 0.40341
3 0.52036E-001 0.19762E-001 -0.27222 0.32426 0.30939
4 0.59765E-001 0.22059E-001 -0.24529 0.30505 0.28806
5 0.70704E-001 -0.51976E-002 -0.13862 0.20932 0.18354
6 0.11906 0.44607E-001 -0.17493 0.29399 0.26474
7 0.25540 0.95993E-002 -0.43110 0.68650 0.60246
8 0.52246E-001 -0.47008E-001 -0.35167 0.40391 0.36456
9 0.32215E-001 -0.62291E-001 -0.28800 0.32021 0.28497
10 0.28072E-001 -0.68269E-001 -0.28304 0.31111 0.27586
11 0.25990E-001 -0.78663E-001 -0.28626 0.31225 0.27527
12 0.26657E-001 -0.79217E-001 -0.29507 0.32173 0.28400
主要问题是,有时列被空格分隔,有时没有空格(' - '符号占据空间),也就是没有适当的字段分隔符。我发现了一个类似的问题here,但该数据在字段分隔符方面是一致的。根据我的想法,可能有两种方式,
我是AWK的新手,我知道使用其他工具可能非常容易,但我想知道是否可以使用awk分离/提取这些列。我在MacOS的终端中使用awk。
答案 0 :(得分:4)
您可以FIELDWIDTHS
块中指定BEGIN
来split fields in a fixed width file in awk:
$ cat test
NODE S1 S2 S3 SINT SEQV
1 0.14919 -0.58396E-001-0.71230 0.86149 0.77873
2 0.56037E-001 0.23261E-002-0.37154 0.42757 0.40341
3 0.52036E-001 0.19762E-001-0.27222 0.32426 0.30939
4 0.59765E-001 0.22059E-001-0.24529 0.30505 0.28806
5 0.70704E-001-0.51976E-002-0.13862 0.20932 0.18354
6 0.11906 0.44607E-001-0.17493 0.29399 0.26474
7 0.25540 0.95993E-002-0.43110 0.68650 0.60246
8 0.52246E-001-0.47008E-001-0.35167 0.40391 0.36456
9 0.32215E-001-0.62291E-001-0.28800 0.32021 0.28497
10 0.28072E-001-0.68269E-001-0.28304 0.31111 0.27586
11 0.25990E-001-0.78663E-001-0.28626 0.31225 0.27527
12 0.26657E-001-0.79217E-001-0.29507 0.32173 0.28400
$ awk 'BEGIN{ FIELDWIDTHS= "5 13 13 13 13"; OFS="|"}{$1=$1}1' test
NODE | S1 | S2 | S3 | SINT
1 | 0.14919 |-0.58396E-001|-0.71230 | 0.86149
2 | 0.56037E-001| 0.23261E-002|-0.37154 | 0.42757
3 | 0.52036E-001| 0.19762E-001|-0.27222 | 0.32426
4 | 0.59765E-001| 0.22059E-001|-0.24529 | 0.30505
5 | 0.70704E-001|-0.51976E-002|-0.13862 | 0.20932
6 | 0.11906 | 0.44607E-001|-0.17493 | 0.29399
7 | 0.25540 | 0.95993E-002|-0.43110 | 0.68650
8 | 0.52246E-001|-0.47008E-001|-0.35167 | 0.40391
9 | 0.32215E-001|-0.62291E-001|-0.28800 | 0.32021
10 | 0.28072E-001|-0.68269E-001|-0.28304 | 0.31111
11 | 0.25990E-001|-0.78663E-001|-0.28626 | 0.31225
12 | 0.26657E-001|-0.79217E-001|-0.29507 | 0.32173
$ awk 'BEGIN{ FIELDWIDTHS= "5 13 13 13 13"; OFS="\t"}{$1=$1}1' test
NODE S1 S2 S3 SINT
1 0.14919 -0.58396E-001 -0.71230 0.86149
2 0.56037E-001 0.23261E-002 -0.37154 0.42757
3 0.52036E-001 0.19762E-001 -0.27222 0.32426
4 0.59765E-001 0.22059E-001 -0.24529 0.30505
5 0.70704E-001 -0.51976E-002 -0.13862 0.20932
6 0.11906 0.44607E-001 -0.17493 0.29399
7 0.25540 0.95993E-002 -0.43110 0.68650
8 0.52246E-001 -0.47008E-001 -0.35167 0.40391
9 0.32215E-001 -0.62291E-001 -0.28800 0.32021
10 0.28072E-001 -0.68269E-001 -0.28304 0.31111
11 0.25990E-001 -0.78663E-001 -0.28626 0.31225
12 0.26657E-001 -0.79217E-001 -0.29507 0.32173
可能需要对这里的任何构成实际字段进行一些调整,但这是它的要点。
答案 1 :(得分:1)
您还可以使用正则表达式解析数字格式,并在每个数字前插入空格:
awk 'NR==1 { print; next } { print gensub(/(-?[0-9]+(\.[0-9]+)?([Ee][+-]?[0-9]+)?)/," \\1", "g") }' FILE
输出:
NODE S1 S2 S3 SINT SEQV
1 0.14919 -0.58396E-001 -0.71230 0.86149 0.77873
2 0.56037E-001 0.23261E-002 -0.37154 0.42757 0.40341
3 0.52036E-001 0.19762E-001 -0.27222 0.32426 0.30939
4 0.59765E-001 0.22059E-001 -0.24529 0.30505 0.28806
5 0.70704E-001 -0.51976E-002 -0.13862 0.20932 0.18354
6 0.11906 0.44607E-001 -0.17493 0.29399 0.26474
7 0.25540 0.95993E-002 -0.43110 0.68650 0.60246
8 0.52246E-001 -0.47008E-001 -0.35167 0.40391 0.36456
9 0.32215E-001 -0.62291E-001 -0.28800 0.32021 0.28497
10 0.28072E-001 -0.68269E-001 -0.28304 0.31111 0.27586
11 0.25990E-001 -0.78663E-001 -0.28626 0.31225 0.27527
12 0.26657E-001 -0.79217E-001 -0.29507 0.32173 0.28400
使用此方法,您不必知道字段数和字段宽度,因此它可以更加强大地防止数据格式更改。
答案 2 :(得分:0)
虽然答案是JNevill& Andriy Makukha他们自己的权利很好,我想使用NAWK(MacOS默认AWK)专门解决问题。我发现“FIELDWIDTHS”只是一个gawk功能Grymoire,machelp。
要抓住的是
FS=""
将每个字符视为字段。由于字段宽度相等,因此当知道每列中的字符数时,可以提取每列。例如,如果我想提取第一,第二,第三和最后一列,我可以使用以下代码(如果源数据命名为:test_input.txt):
awk 'BEGIN{FS=""}{print $1$2$3$4"\t"$5$6$7$8$9$10$11$12$13$14$15$16$17$18"\t"$19$20$21$22$23$24$25$26$27$28$29$30$31"\t"$59$60$61$62$63$64$65$66$67$68$69$70}' test_input.txt
输出:
NODE S1 S2 SEQV
1 0.14919 -0.58396E-001 0.77873
2 0.56037E-001 0.23261E-002 0.40341
3 0.52036E-001 0.19762E-001 0.30939
4 0.59765E-001 0.22059E-001 0.28806
5 0.70704E-001 -0.51976E-002 0.18354
6 0.11906 0.44607E-001 0.26474
7 0.25540 0.95993E-002 0.60246
8 0.52246E-001 -0.47008E-001 0.36456
9 0.32215E-001 -0.62291E-001 0.28497
10 0.28072E-001 -0.68269E-001 0.27586
11 0.25990E-001 -0.78663E-001 0.27527
12 0.26657E-001 -0.79217E-001 0.28400
这是一个简单但有些简单的解决方案,但对于大数据来说,它现在对我来说很有用。任何进一步的改进都将受到欢迎......