如何解析在TSV内流离失所的空列?

时间:2014-02-26 23:54:00

标签: perl sed awk

我有一个我要解析的TSV文件。所有列中都有空字段导致列的顺序位移,因此我使用某个列号得到的所有值实际上都不是来自该列。

某些字段包含长字符串,其中包含空格。此外,某些列包含潜在的分隔符,例如; | :

输入文件

 columnA    columnB    columnC    columnD
 A1         B1         C1         D1
 B2         C2         D2    
 A3         D3
 A4         B4         D4

期望的输出

 columnA    columnB    columnC    columnD
 A1         B1         C1         D1
            B2         C2         D2    
 A3                               D3
 A4         B4                    D4

$file myfile

`ASCII English text, with very long lines` 

$awk '-F\t' '{print NF}' myfile | sort | uniq -c | tail -n

`247871 136`

我发现这个代码是在回复类似问题(https://unix.stackexchange.com/questions/29023/how-to-display-tsv-csv-in-console-when-empty-cells-are-missed-by-column-t)时发布的,但我无法为我的文件工作:

sed ':x s/\(^\|\t\)\t/\1 \t/; t x' < file.tsv | column -t -s $'\t'

(导入Excel后问题仍然存在。)

2 个答案:

答案 0 :(得分:0)

FieldEmpty='   '
FieldSize=${#FieldEmpty}

sed "
s/A/&/
t B
s/^ */ ${FieldEmpty}/
t B

: B
s/B/&/
t C
s/^ .\{${FieldSize}\}/&${FieldEmpty}/
t C

: C
s/C/&/
t D
s/^ \(.\{${FieldSize}\}\)\{2\}/&${FieldEmpty}/
t D

: D
s/D/&/
t
s/^ \(.\{${FieldSize}\}\)\{3\}/&${FieldEmpty}/
" YourFile

如果使用更多列,则使用迭代方式(测试/“插入”的相同概念)

在我的AIX / KSH上(所以应该与GNU上的--posix -e相同)

$ cat YourFile
 columnA    columnB    columnC    columnD
 A1         B1         C1         D1
 B2         C2         D2
 A3         D3
 A4         B4         D4
$ FieldEmpty='           ';FieldSize=${#FieldEmpty};echo $FieldSize
11
$sed "..." YourFile
 columnA    columnB    columnC    columnD
 A1         B1         C1         D1
            B2         C2         D2
 A3                               D3
 A4         B4                    D4

答案 1 :(得分:0)

如果您的文件是制表符分隔的,则应使用tab作为awk中的字段分隔符。像

$ column -t -s $'\t' file

columnA  columnB  columnC  columnD
A1 1     B1 2     C1 3     D1 4
B2 2     C2 4     D2 4
A3 1     D3 4
A4 1     B4 2     D4 4

$xxd file
0000000: 636f 6c75 6d6e 4109 636f 6c75 6d6e 4209  columnA.columnB.
0000010: 636f 6c75 6d6e 4309 636f 6c75 6d6e 440a  columnC.columnD.
0000020: 4131 2031 0942 3120 3209 4331 2033 0944  A1 1.B1 2.C1 3.D
0000030: 3120 340a 0942 3220 3209 4332 2034 0944  1 4..B2 2.C2 4.D
0000040: 3220 340a 4133 2031 0909 0944 3320 340a  2 4.A3 1...D3 4.
0000050: 4134 2031 0942 3420 3209 0944 3420 340a  A4 1.B4 2..D4 4.

$ awk -F'\t' '{
    for (i=1; i<=NF; i++) {
        printf "%-8s ", $i
    }
    print ""
}'

columnA columnB columnC columnD 
A1 1    B1 2    C1 3    D1 4    
        B2 2    C2 4    D2 4    
A3 1                    D3 4    
A4 1    B4 2            D4 4 
相关问题