Обработка текста — транспонировать столбец в строки в зависимости от значения

Добавление initcall_blacklist=i2c_dw_init_masterв строку команды ядра -должно предотвратить инициализацию драйвера Designware во время загрузки и полностью устранить проблему.

См. параметры ядра для очень краткого описания initcall_blacklistи поток вокруг патча для более полезной справочной информации.

3
28.08.2019, 13:20
3 ответа

Хороший способ сделать это — использовать ассоциативный массив или хэш. Ключом для каждого хэша является первое поле (. Я буду называть их «идентификаторами» из-за отсутствия лучшего термина ), а значения, хранящиеся для каждого ключа, будут либо строкой, содержащей запятую -, разделенную список значений, видимых для этого идентификатора, или массив, содержащий то же самое.

авк:

В этой версии awk используется строка, разделенная запятыми -, потому что (в awk )это проще, чем работать с ассоциативным массивом, содержащим массив.

#!/usr/bin/awk -f

BEGIN {
  FS=" *, *";
  OFS="";
}

{
  key=$1; $1=""; $0=$0;

  if (length(ids[key]) > 0) {
    ids[key]=ids[key]","$0;
   } else {
    ids[key] = $0
   };
}

END {
  for (k in ids) {
    print k "," ids[k]
  }
}

В perl не сложнее (и намного полезнее/гибче )работать с хэшем массивов (или "HoA" ), чем с конкатенированной строкой:

#!/usr/bin/perl -w

use strict;

my %ids = ();

while(<>) {
  chomp;
  my @F = split /\s*,\s*/;
  push @{ $ids{$F[0]} }, $F[1];
};


END {
  foreach my $key (keys %ids) {
    print $key. ','.  join(",",@{ $ids{$key} }), "\n";
  }
}

Вывод для версий awk и perl одинаков:

71w - Ukr,307200,51200
71w - Bar,1280000,102400,2048000
71w - Res,153600
71w - Upg,358400
71w - Sin,358400
71w - Mic,102400,51200
71w - May,20480
71w - Tha,512000,972800
71w - Jul,256000,51200
71w - Uni,51200
71w - Ind,50176,40960
71w - Pro,256000
71w - Rus,51200
71w - Leg,20480
71w - Phi,307200

Обратите внимание, :вывод как для awk, так и для perl версии не в каком-либо определенном порядке,и, вероятно, будет появляться в другом порядке каждый раз, когда вы его запускаете. Это потому, что awk "ассоциативные массивы" и perl "хэши" (два названия одного и того же )по своей сути неупорядочены.

При желании вы можете направить вывод на sort. или в Perl вы можете использовать:

      foreach my $key (sort keys %ids) {

вместо:

      foreach my $key (keys %ids) {

Кроме того, -поскольку мы храним отдельные значения для каждого идентификатора в массиве, в Perl также легко сортировать эти значения. например. замените весь блок ENDв версии Perl на:

END {
  foreach my $key (sort keys %ids) {
    print $key. ','.  join(",",sort @{ $ids{$key} }), "\n";
  }
}

и вывод будет:

71w - Bar,102400,1280000,2048000
71w - Ind,40960,50176
71w - Jul,256000,51200
71w - Leg,20480
71w - May,20480
71w - Mic,102400,51200
71w - Phi,307200
71w - Pro,256000
71w - Res,153600
71w - Rus,51200
71w - Sin,358400
71w - Tha,512000,972800
71w - Ukr,307200,51200
71w - Uni,51200
71w - Upg,358400
3
27.01.2020, 21:15

Использование GNUdatamash:

$ datamash -t, -g 1 collapse 2 < file.csv
71w - Rus,51200
71w - Phi,307200
71w - Ukr,307200,51200
71w - Mic,102400,51200
71w - Jul,256000,51200
71w - Pro,256000
71w - Uni,51200
71w - Ind,50176,40960
71w - Sin,358400
71w - May,20480
71w - Tha,512000,972800
71w - Bar,1280000,102400,2048000
71w - Upg,358400
71w - Leg,20480
71w - Res,153600

Отсортированный вывод с помощью-s:

$ datamash -s -t, -g 1 collapse 2 < file.csv
71w - Bar,1280000,102400,2048000
71w - Ind,50176,40960
71w - Jul,256000,51200
71w - Leg,20480
71w - May,20480
71w - Mic,102400,51200
71w - Phi,307200
71w - Pro,256000
71w - Res,153600
71w - Rus,51200
71w - Sin,358400
71w - Tha,512000,972800
71w - Ukr,307200,51200
71w - Uni,51200
71w - Upg,358400

Описание вариантов:

  • -sсортировать ввод перед группировкой
  • -t,использовать запятую в качестве разделителя полей
  • -g 1группа в первом поле
  • collapse 2коллапс на втором поле

Взгляните на пример "свернуть" в руководстве .

2
27.01.2020, 21:15

Предполагая, что ваш ввод сгруппирован или может быть, например, путем сортировки, сгруппирован по значениям $1, как показано в вашем вводе:

$ cat tst.awk
BEGIN { FS=OFS="," }
$1 != prev { if (NR>1) print rec; rec=prev=$1 }
{ rec = rec OFS $2 }
END { print rec }

.

$ awk -f tst.awk file
71w - Rus,51200
71w - Phi,307200
71w - Ukr,307200,51200
71w - Mic,102400,51200
71w - Jul,256000,51200
71w - Pro,256000
71w - Uni,51200
71w - Ind,50176,40960
71w - Sin,358400
71w - May,20480
71w - Tha,512000,972800
71w - Bar,1280000,102400,2048000
71w - Upg,358400
71w - Leg,20480
71w - Res,153600

или если вы предпочитаете краткость ясности:

$ awk -F, '$1!=p{if(NR>1)print r;r=p=$1}{r=r FS$2}END{print r}' file
71w - Rus,51200
71w - Phi,307200
71w - Ukr,307200,51200
71w - Mic,102400,51200
71w - Jul,256000,51200
71w - Pro,256000
71w - Uni,51200
71w - Ind,50176,40960
71w - Sin,358400
71w - May,20480
71w - Tha,512000,972800
71w - Bar,1280000,102400,2048000
71w - Upg,358400
71w - Leg,20480
71w - Res,153600
0
27.01.2020, 21:15

Теги

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