从不同的行打印不同的字段

时间:2014-05-06 03:52:45

标签: awk sed

我有一个如下所示的文件

G1 A1 X 3 6 NA 7 NA NA NA 7 NA NA
G1 B1 X NA NA NA NA NA NA NA NA 7 6
G1 C1 X NA 1 3 4 NA NA NA NA NA NA
G2 D1 Y NA NA NA 1 NA NA NA NA NA NA
G2 E1 Y 2 NA NA NA NA NA NA NA NA NA
G2 F1 Y NA NA NA NA 0 NA NA NA NA NA
G1 G1 Y NA NA NA NA NA 8 7 NA NA NA
G2 H1 X NA NA NA NA NA NA NA NA NA NA

现在我要打印那些不等于NA的字段。我再次不想更改前三列格式,但之后我想打印以逗号分隔的剩余字段,我想要的输出文件

G1 A1 X 3, 6, 7, 7 
G1 B1 X 7, 6
G1 C1 X 1, 3, 4
G2 D1 Y 1
G2 E1 Y 2 
G2 F1 Y 0 
G1 G1 Y 8, 7 
G2 H1 X

我试过

sed 's/NA//g' file| sed 's/\t/ /g'| sed 's/ \+/, /g'

但它也改变了前三列的格式。你能为此提出一些建议。

由于

4 个答案:

答案 0 :(得分:3)

我们在这里awk

awk '{gsub(/ NA/,"");for (i=4;i<NF;i++) $i=$i","}1' file
G1 A1 X 3, 6, 7, 7
G1 B1 X 7, 6
G1 C1 X 1, 3, 4
G2 D1 Y 1
G2 E1 Y 2
G2 F1 Y 0
G1 G1 Y 8, 7
G2 H1 X

答案 1 :(得分:1)

这很复杂,我可以达到perl。

perl -pe '
    chomp; s/\s+/ /g; s/ $//; s/^ //;
    my ($left, $right) = /(\S+ \S+ \S+) (.+)$/;
    $right =~ s/\bNA\b//g;
    $right =~ s/^ +//;
    $right =~ s/ +$//;
    $right =~ s/ +/, /g;
    $_ = "$left $right";
    s/ *$/\n/;
'

对你的测试用例进行DTRT,有人比我更聪明和/或更少困,也许可以将它打下来。

答案 2 :(得分:0)

以下是使用awk的另一种方式:

awk '{gsub(/NA/,"");$1=$1;for(i=4;i<=NF;i++)$i=(i==NF?$i:$i",")}1' file
G1 A1 X 3, 6, 7, 7
G1 B1 X 7, 6
G1 C1 X 1, 3, 4
G2 D1 Y 1
G2 E1 Y 2
G2 F1 Y 0
G1 G1 Y 8, 7
G2 H1 X

或使用GNU sed

sed -e 's/\bNA\b//g' -e 's/ \+/ /g' -e 's/ *$//' -e 's/ /, /4g' file
G1 A1 X 3, 6, 7, 7
G1 B1 X 7, 6
G1 C1 X 1, 3, 4
G2 D1 Y 1
G2 E1 Y 2
G2 F1 Y 0
G1 G1 Y 8, 7
G2 H1 X

答案 3 :(得分:0)

sed ':a
s/\(\([^]\{1,\} \{1,\}\)\{2\}[^ ]\{1,\}\)\(.*\) NA/\1\3/
t a
' YourFile

normaly也应该使用泛型类[:blank:]而不是空格字符(下面的代码)但在我的系统上奇怪失败

sed ':a
s/\(\([^[:blank:]]\{1,\}[:blank:]\{1,\}\)\{2\}[^[:blank:]]\{1,\}\)\(.*\)[:blank:]NA/\1\3/
t a
' YourFile