AWK:如何从 CSV 中删除重复的标题行?

Hot*_*AMS 3 awk

处理由几个 CSV 的串联产生的 csv,我正在寻找删除标题行重复的可能性(存在于每个串联的 CSV 中,它们之间是相同的)。这是我的 CSV 包含重复的第一行:

ID(Prot),   ID(lig),    ID(cluster),    dG(rescored),   dG(before), POP(before)
1000,   lig40,  1,  0.805136,   -5.5200,    79
1000,   lig868, 1,  0.933209,   -5.6100,    42
1000,   lig278, 1,  0.933689,   -5.7600,    40
1000,   lig619, 3,  0.946354,   -7.6100,    20
1000,   lig211, 1,  0.960048,   -5.2800,    39
1000,   lig40,  2,  0.971051,   -4.9900,    40
1000,   lig868, 3,  0.986384,   -5.5000,    29
1000,   lig12,  3,  0.988506,   -6.7100,    16
1000,   lig800, 16, 0.995574,   -4.5300,    40
1000,   lig800, 1,  0.999935,   -5.7900,    22
1000,   lig619, 1,  1.00876,    -7.9000,    3
1000,   lig619, 2,  1.02254,    -7.6400,    1
1000,   lig12,  1,  1.02723,    -6.8600,    5
1000,   lig12,  2,  1.03273,    -6.8100,    4
1000,   lig211, 2,  1.03722,    -5.2000,    19
1000,   lig211, 3,  1.03738,    -5.0400,    21
ID(Prot),   ID(lig),    ID(cluster),    dG(rescored),   dG(before), POP(before)
10V1,   lig40,  1,  0.513472,   -6.4600,    150
10V1,   lig211, 2,  0.695981,   -6.8200,    91
10V1,   lig278, 1,  0.764432,   -7.0900,    70
10V1,   lig868, 1,  0.787698,   -7.3100,    62
10V1,   lig211, 1,  0.83416,    -6.8800,    54
10V1,   lig868, 3,  0.888408,   -6.4700,    44
10V1,   lig278, 2,  0.915932,   -6.6600,    35
10V1,   lig12,  1,  0.922741,   -9.3600,    19
10V1,   lig12,  8,  0.934144,   -7.4600,    24
10V1,   lig40,  2,  0.949955,   -5.9000,    34
10V1,   lig800, 5,  0.964194,   -5.9200,    30
10V1,   lig868, 2,  0.966243,   -6.9100,    20
10V1,   lig12,  2,  0.972575,   -8.3000,    10
10V1,   lig619, 6,  0.979168,   -8.1600,    9
10V1,   lig619, 4,  0.986202,   -8.7800,    5
10V1,   lig800, 2,  0.989599,   -6.2400,    20
10V1,   lig619, 1,  0.989725,   -9.2900,    3
10V1,   lig12,  7,  0.991535,   -7.5800,    9
ID(Prot),   ID(lig),    ID(cluster),    dG(rescored),   dG(before), POP(before)
10V2,   lig40,  1,  0.525767,   -6.4600,    146
10V2,   lig211, 2,  0.744702,   -6.8200,    78
10V2,   lig278, 1,  0.749015,   -7.0900,    74
10V2,   lig868, 1,  0.772025,   -7.3100,    66
10V2,   lig211, 1,  0.799829,   -6.8700,    63
10V2,   lig12,  1,  0.899345,   -9.1600,    25
10V2,   lig12,  4,  0.899606,   -7.5500,    32
10V2,   lig868, 3,  0.903364,   -6.4800,    40
10V2,   lig278, 3,  0.913145,   -6.6300,    36
10V2,   lig800, 5,  0.94576,    -5.9100,    35
Run Code Online (Sandbox Code Playgroud)

要对这个 CSV 进行后处理,我需要删除重复的标题行

ID(Prot),   ID(lig),    ID(cluster),    dG(rescored),   dG(before), POP(before)
Run Code Online (Sandbox Code Playgroud)

将标题仅保留在融合 csv 的开头(在第一行!)。我尝试使用以下 awk one-liner,它正在寻找第一行,然后删除其重复

 awk '{first=$1;gsub("ID(Prot)","");print first,$0}' mycsv.csv > csv_without_repeats.csv
Run Code Online (Sandbox Code Playgroud)

但是它无法识别标题行,这意味着模式定义不正确。

如何更正我的 AWK 代码,假设应该进一步通过管道对其他代码进行排序,以便在过滤重复后对行进行排序?

awk '{first=$1;gsub(/ID(Prot)?(\([-azA-Z]+\))?/,"");print first,$0}' | LC_ALL=C sort -k4,4g input.csv > sorted_and_without_repeats.csv
Run Code Online (Sandbox Code Playgroud)

ter*_*don 10

这是一个awk脚本,它将跳过任何以 开头的行ID(Prot),除非它是第一行:

awk 'NR==1 || !/^ID\(Prot\)/' file > newFile
Run Code Online (Sandbox Code Playgroud)

这是相同的想法perl

perl -ne 'print if $.==1 || !/^ID\(Prot\)/' file > newFile
Run Code Online (Sandbox Code Playgroud)

或者,就地编辑原始文件:

perl -i -ne 'print if $.==1 || !/^ID\(Prot\)/' file 
Run Code Online (Sandbox Code Playgroud)


Dan*_*ini 10

使用 POSIX 兼容sed(在GNU sed和 上 测试busybox sed):

sed '1!{/^ID/d;}' data
Run Code Online (Sandbox Code Playgroud)

当以ID.开头时,删除除第一行之外的所有行。某些sed实现可以-i选择启用就地编辑文件。


awk

awk 'NR == 1 {h=$0; print} $0 == h {next}1' data
Run Code Online (Sandbox Code Playgroud)

如果我们在第一行保存标题并打印它,那么对于每一行我们处理如果这等于标题跳过它,否则打​​印它。


或相同的perl

perl -lne '$h = $_ if $. == 1; print if($_ ne $h || $. == 1)' data
Run Code Online (Sandbox Code Playgroud)

添加-i允许perl就地编辑文件的选项。

  • +1。并且可以缩写为`awk'NR==1{h=$0; 打印}; ($0 != h) '输入`。 (2认同)

gue*_*t_7 7

这是使用该awk实用程序处理 pbm 的一种简单方法。但请注意,即使标题中存在更少/更多空间,它们也会包含在输出中。

awk '
  NR>1&&$0==hdr{next}
  NR==1{hdr=$0}1
' file
Run Code Online (Sandbox Code Playgroud)

相同的方法,但在流编辑器实用程序 sed 中:

sed -En '
  1h;1!G;/^(.*)\n\1$/!P
' file
Run Code Online (Sandbox Code Playgroud)


Kus*_*nda 6

grep -v -F -x -f <( head -n 1 file.csv | tee file-new.csv ) file.csv >>file-new.csv
Run Code Online (Sandbox Code Playgroud)

这是使用具有进程替换 ( <(...))的 shell ,例如bashzsh,使用 来从文件中获取标题行,使用head将其写入新文件tee,然后使用 过滤掉原始文件中的所有标题行grep。过滤后的行将附加到新文件中,在先前由tee.

这种做法并不取决于标题实际上什么。它只是从原始文件中提取恰好与文件第一行不同的所有行。

没有进程替换:

head -n 1 file.csv | tee file-new.csv |
grep -v -F -x -f /dev/stdin file.csv >>file-new.csv
Run Code Online (Sandbox Code Playgroud)


Ed *_*ton 5

$ awk 'NR==1{h=$0; print} $0!=h' file
ID(Prot),   ID(lig),    ID(cluster),    dG(rescored),   dG(before), POP(before)
1000,   lig40,  1,  0.805136,   -5.5200,    79
1000,   lig868, 1,  0.933209,   -5.6100,    42
1000,   lig278, 1,  0.933689,   -5.7600,    40
1000,   lig619, 3,  0.946354,   -7.6100,    20
1000,   lig211, 1,  0.960048,   -5.2800,    39
1000,   lig40,  2,  0.971051,   -4.9900,    40
1000,   lig868, 3,  0.986384,   -5.5000,    29
1000,   lig12,  3,  0.988506,   -6.7100,    16
1000,   lig800, 16, 0.995574,   -4.5300,    40
1000,   lig800, 1,  0.999935,   -5.7900,    22
1000,   lig619, 1,  1.00876,    -7.9000,    3
1000,   lig619, 2,  1.02254,    -7.6400,    1
1000,   lig12,  1,  1.02723,    -6.8600,    5
1000,   lig12,  2,  1.03273,    -6.8100,    4
1000,   lig211, 2,  1.03722,    -5.2000,    19
1000,   lig211, 3,  1.03738,    -5.0400,    21
10V1,   lig40,  1,  0.513472,   -6.4600,    150
10V1,   lig211, 2,  0.695981,   -6.8200,    91
10V1,   lig278, 1,  0.764432,   -7.0900,    70
10V1,   lig868, 1,  0.787698,   -7.3100,    62
10V1,   lig211, 1,  0.83416,    -6.8800,    54
10V1,   lig868, 3,  0.888408,   -6.4700,    44
10V1,   lig278, 2,  0.915932,   -6.6600,    35
10V1,   lig12,  1,  0.922741,   -9.3600,    19
10V1,   lig12,  8,  0.934144,   -7.4600,    24
10V1,   lig40,  2,  0.949955,   -5.9000,    34
10V1,   lig800, 5,  0.964194,   -5.9200,    30
10V1,   lig868, 2,  0.966243,   -6.9100,    20
10V1,   lig12,  2,  0.972575,   -8.3000,    10
10V1,   lig619, 6,  0.979168,   -8.1600,    9
10V1,   lig619, 4,  0.986202,   -8.7800,    5
10V1,   lig800, 2,  0.989599,   -6.2400,    20
10V1,   lig619, 1,  0.989725,   -9.2900,    3
10V1,   lig12,  7,  0.991535,   -7.5800,    9
10V2,   lig40,  1,  0.525767,   -6.4600,    146
10V2,   lig211, 2,  0.744702,   -6.8200,    78
10V2,   lig278, 1,  0.749015,   -7.0900,    74
10V2,   lig868, 1,  0.772025,   -7.3100,    66
10V2,   lig211, 1,  0.799829,   -6.8700,    63
10V2,   lig12,  1,  0.899345,   -9.1600,    25
10V2,   lig12,  4,  0.899606,   -7.5500,    32
10V2,   lig868, 3,  0.903364,   -6.4800,    40
10V2,   lig278, 3,  0.913145,   -6.6300,    36
10V2,   lig800, 5,  0.94576,    -5.9100,    35
Run Code Online (Sandbox Code Playgroud)