AWK :как удалить повторяющиеся строки заголовков из CSV?

Если количество строк нечетное, то tput cupочищает всю страницу.
запись таким образом должна исправить это:

tput cup $(($(stty size|awk '{print $1}')/2)) 0 && tput ed
3
28.05.2021, 12:09
8 ответов

Вот скрипт awk, который пропускает все строки, начинающиеся с ID(Prot), кроме первой строки:

awk 'NR==1 || !/^ID\(Prot\)/' file > newFile

Вот та же идея вperl:

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

Или, чтобы отредактировать исходный файл на месте:

perl -i -ne 'print if $.==1 || !/^ID\(Prot\)/' file 
10
28.07.2021, 11:28

Вот один простой способ справиться с pbm с помощью утилиты awk. Но имейте в виду, что даже если места меньше/больше в заголовках, тогда они будут включены в вывод.

awk '
  NR>1&&$0==hdr{next}
  NR==1{hdr=$0}1
' file

Тот же подход, но в утилите редактора потоков sed:

sed -En '
  1h;1!G;/^(.*)\n\1$/!P
' file
7
28.07.2021, 11:28
grep -v -F -x -f <( head -n 1 file.csv | tee file-new.csv ) file.csv >>file-new.csv

Это использует оболочку, которая имеет подстановки процессов (<(...)), такие как bashили zsh, чтобы получить строку заголовка из файла с помощью 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
6
28.07.2021, 11:28

С POSIX -совместимым sed(, протестированным на GNU sedиbusybox sed):

sed '1!{/^ID/d;}' data

Удалить всю строку, кроме первой, если она начинается с ID. В некоторых реализациях sedесть опция -i, позволяющая редактировать файл на месте.


awk:

awk 'NR == 1 {h=$0; print} $0 == h {next}1' data

Если мы в первой строке сохраняем заголовок и печатаем его, то для каждой строки обрабатываем, если это равно заголовку пропускаем его, иначе печатаем.


Или то же самое вperl:

perl -lne '$h = $_ if $. == 1; print if($_ ne $h || $. == 1)' data

Добавьте опцию -i, позволяющую perlредактировать файл на месте.

10
28.07.2021, 11:28
$ 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
5
28.07.2021, 11:28

Эта команда awk должна работать независимо от заголовка. Он сохраняет первую строку в качестве заголовка и печатает следующие строки только в том случае, если они отличаются от сохраненного заголовка. Это будет работать до тех пор, пока повторяющиеся заголовки строго одинаковы.

awk 'NR==1 && header=$0; $0!=header' originalfile > newfile

2
28.07.2021, 11:28
 awk '{if(!seen[$0]++)print $0}' filename

выход

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
0
28.07.2021, 11:28

Вы также можете использовать grepпосле пропуска первой строки:

{
  head -n1
  grep -v '^ID'
} < file.csv

Это предполагает, что file.csvявляется обычным файлом, (не будет работать с каналом с большинством headреализаций )и что headсовместим с POSIX в том, что он оставит курсор в стандартном вводе сразу после первой строки.

Чтобы пропустить все строки, идентичные первой, вы можете:

{
  IFS= read -r header       &&
    printf '%s\n' "$header" &&
    grep -Fxe "$header"
} < file.csv
2
28.07.2021, 11:28

Теги

Похожие вопросы