Заменить пустые места в столбце символом - PullRequest
0 голосов
/ 07 сентября 2018

Мой файл выглядит так:

  Scenario 1                                     0.20          0.00     0.00 r
  Scenario 2                                     0.08          0.34 &   0.34 r
  Scenario 3                          6   12.95 
  Scenario 4                              0.00   0.08   0.00   0.00 &   0.35 r
  Scenario 5                                     0.07          0.08 &   0.42 r
  Scenario 6                          6   8.70 
  Scenario 7                              0.00   0.07   0.00   0.00 &   0.42 r
  Scenario 8                                     0.31          0.28 &   0.70 f
  Scenario 9                          5   5.06 

Мои цели : Для замены столбцов пустыми ячейками / пробелами / отсутствующими значениями на «-» (всего 8 полей)

Проблема, с которой я сталкиваюсь при использовании команды awk, заключается в том, что разделитель полей постоянно меняется с каждой строкой.

Что я сделал до сих пор: Я извлек строки, которые имеют определенные шаблоны полей и поместил их в разные файлы. Например: я поместил сценарии 3, 6 и 9 в один файл, а остальные в другой файл, чтобы упростить работу с данными. Теперь у меня есть:

Файл 1:

Scenario 3                          6   12.95
Scenario 6                          6   8.70
Scenario 9                          5   5.06

Файл 2:

  Scenario 1                                     0.20          0.00     0.00 r
  Scenario 2                                     0.08          0.34 &   0.34 r

  Scenario 4                              0.00   0.08   0.00   0.00 &   0.35 r
  Scenario 5                                     0.07          0.08 &   0.42 r

  Scenario 7                              0.00   0.07   0.00   0.00 &   0.42 r
  Scenario 8                                     0.31          0.28 &   0.70 f

Ожидаемый результат:

  Scenario 1                          -     -    0.20    -     0.00     0.00 r
  Scenario 2                          -     -    0.08    -     0.34 &   0.34 r
  Scenario 3                          6   12.95   -      -      -        -
  Scenario 4                          -   0.00   0.08   0.00   0.00 &   0.35 r
  Scenario 5                          -     -    0.07    -     0.08 &   0.42 r
  Scenario 6                          6   8.70    -      -      -        -
  Scenario 7                          -   0.00   0.07   0.00   0.00 &   0.42 r
  Scenario 8                          -     -    0.31          0.28 &   0.70 f
  Scenario 9                          5   5.06    -      -      -        -

Случай 1 (с использованием awk с FIELDWIDTHS):

  $ awk 'BEGIN { FIELDWIDTHS="37 3 7 7 7 9 9 "} {for(i=1;i<=NF;++i){printf $i"|"};print""}' main1.txt

| I_BLENDER_0/R_137/CLK (SDFFX2_HVT) |   |       |  0.20 |       |  0.00   |  0.00 r
| I_BLENDER_0/R_137/Q (SDFFX2_HVT)   |   |       |  0.08 |       |  0.34 & |  0.34 r
| I_BLENDER_0/n2757 (net)            | 6 |  12.95|
| I_BLENDER_0/U4847/A1 (AND2X1_LVT)  |   |  0.00 |  0.08 |  0.00 |  0.00 & |  0.35 r
| I_BLENDER_0/U4847/Y (AND2X1_LVT)   |   |       |  0.07 |       |  0.08 & |  0.42 r
| I_BLENDER_0/n2616 (net)            | 6 |  8.70 |
| I_BLENDER_0/U1/A4 (NAND4X0_HVT)    |   |  0.00 |  0.07 |  0.00 |  0.00 & |  0.42 r
| I_BLENDER_0/U1/Y (NAND4X0_HVT)     |   |       |  0.31 |       |  0.28 & |  0.70 f

Случай 2 (с помощью команды sed):

  $  sed "s/^\(.\{,36\}\)$/\1`echo -$_{1..30}|tr -d '-'`/;
      s/^\(.\{38\}\) /\1-/;
      s/^\(.\{43\}\) /\1-/;
      s/^\(.\{50\}\) /\1-/;
      s/^\(.\{57\}\) /\1-/;
      s/^\(.\{64\}\) /\1-/;
      s/^\(.\{73\}\) /\1-/;
      s/ *$//"



  I_BLENDER_0/R_137/CLK (SDFFX2_HVT)  -    -     0.20    -     0.00     0.00 r
  I_BLENDER_0/R_137/Q (SDFFX2_HVT)    -    -     0.08    -     0.34 &   0.34 r
  I_BLENDER_0/n2757 (net)             6   12.95
  I_BLENDER_0/U4847/A1 (AND2X1_LVT)   -   0.00   0.08   0.00   0.00 &   0.35 r
  I_BLENDER_0/U4847/Y (AND2X1_LVT)    -    -     0.07    -     0.08 &   0.42 r
  I_BLENDER_0/n2616 (net)             6   8.70

Ответы [ 3 ]

0 голосов
/ 07 сентября 2018

Для этого вы можете использовать FIELDWIDTHS в Gnu awk:

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

$ awk 'BEGIN{ FIELDWIDTHS="13 25 2 7 7 7 9 9"}
       {for(i=1;i<=NF;++i){printf $i"|"};print""}' file

  Scenario 1 |                        |   |       |  0.20 |       |  0.00   |  0.00 r|
  Scenario 2 |                        |   |       |  0.08 |       |  0.34 & |  0.34 r|
  Scenario 3 |                        | 6 |  12.95| ||||
  Scenario 4 |                        |   |  0.00 |  0.08 |  0.00 |  0.00 & |  0.35 r|
  Scenario 5 |                        |   |       |  0.07 |       |  0.08 & |  0.42 r|
  Scenario 6 |                        | 6 |  8.70 |||||
  Scenario 7 |                        |   |  0.00 |  0.07 |  0.00 |  0.00 & |  0.42 r|
  Scenario 8 |                        |   |       |  0.31 |       |  0.28 & |  0.70 f|
  Scenario 9 |                        | 5 |  5.06 |||||

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

$ awk 'BEGIN{ FIELDWIDTHS="13 24 3 7 7 7 9 9"}
       {s=$1$2}
       {s=s ($3~/^[[:blank:]]*$/?" - ":$3)}
       {s=s ($4~/^[[:blank:]]*$/?"   -   ":$4)}
       {s=s ($5~/^[[:blank:]]*$/?"   -   ":$5)}
       {s=s ($6~/^[[:blank:]]*$/?"   -   ":$6)}
       {s=s ($7~/^[[:blank:]]*$/?"   -     ":$7)}
       {s=s ($8~/^[[:blank:]]*$/?"   -     ":$8)}
       {print s}' file

и это дает:

  Scenario 1                          -    -     0.20    -     0.00     0.00 r
  Scenario 2                          -    -     0.08    -     0.34 &   0.34 r
  Scenario 3                          6   12.95   -      -      -        -     
  Scenario 4                          -   0.00   0.08   0.00   0.00 &   0.35 r
  Scenario 5                          -    -     0.07    -     0.08 &   0.42 r
  Scenario 6                          6   8.70    -      -      -        -     
  Scenario 7                          -   0.00   0.07   0.00   0.00 &   0.42 r
  Scenario 8                          -    -     0.31    -     0.28 &   0.70 f
  Scenario 9                          5   5.06    -      -      -        -     

примечания:

  • было бы лучше использовать реальное форматирование, которое использовалось для настройки этих файлов.
  • Я всегда оставляю дополнительный пробел перед полями, чтобы учесть возможные знаки минуса
  • Похоже, что числа написаны в формате %-5.2f. Вот почему число 12.95 не выровнено. (%6.2f было бы лучше)

примечание: если вы немного поиграете, вы можете сделать это короче. Но вы как бы теряете чувство происходящего.

awk 'BEGIN{ FIELDWIDTHS="13 23 5 7 7 7 9 9"} 
     {for(i=3;i<=NF;++i)$i=$i~/^[[:blank:]]*$/?"  -":$i}
     {printf "%-13s%-23s%-5s%-7s%-7s%-7s%-9s%-9s\n",$1,$2,$3,$4,$5,$6,$7,$8}' file

или даже короче

awk 'BEGIN{ FIELDWIDTHS="36 5 7 7 7 9 9"; split(FIELDWIDTHS,a)}
     {for(i=1;i<=NF;++i) printf "%-*s",a[i], ($i~/^ *$/?"  -":$i); print ""}'
0 голосов
/ 07 сентября 2018

Использование GNU awk и переменной FIELDWIDTHS для разделения полей по их длине:

awk 'BEGIN{
      FIELDWIDTHS="38 4 7 7 7 9 6"
      colnr=split(FIELDWIDTHS,a," ")
    } 
    {
      for(i=1;i<=colnr;i++){
        $i=sprintf("%-"a[i]"s",((!$i&&$i!=0)||$i~/^ *$/?"-":$i))
      }
    }1' file
  Scenario 1                           -    -       0.20    -       0.00      0.00 r
  Scenario 2                           -    -       0.08    -       0.34 &    0.34 r
  Scenario 3                           6    12.95   -       -       -         -
  Scenario 4                           -    0.00    0.08    0.00    0.00 &    0.35 r
  Scenario 5                           -    -       0.07    -       0.08 &    0.42 r
  Scenario 6                           6    8.70    -       -       -         -
  Scenario 7                           -    0.00    0.07    0.00    0.00 &    0.42 r
  Scenario 8                           -    -       0.31    -       0.28 &    0.70 f
  Scenario 9                           5    5.06    -       -       -         -

Блок BEGIN устанавливает массив a с длиной всех полей и сохраняет количество полей в переменной colnr.

Блок по умолчанию проходит по всем полям и переписывает их с помощью функции sprintf().
Если поле содержит только пробелы $i~/^ *$/ или не существует !$i&&$i!=0, замените его на -. Если нет, поле остается нетронутым.

0 голосов
/ 07 сентября 2018

К сожалению, в этом случае вам нужно тщательно посчитать столбцы символов. Вот код для ввода, который вы предоставили - вам может потребоваться настроить числа для вашего реального файла ввода.

sed "s/^\(.\{,78\}\)$/\1`echo -$_{1..78}|tr -d '-'`/;
  s/^\(.\{38\}\) /\1-/;
  s/^\(.\{43\}\) /\1-/;
  s/^\(.\{50\}\) /\1-/;
  s/^\(.\{57\}\) /\1-/;
  s/^\(.\{64\}\) /\1-/;
  s/^\(.\{73\}\) /\1-/;
  s/ *$//" input_file

Здесь первая строка добавляет пробелы в конце строки в случае, если строка заканчивается до достижения 78 символов - это затем используется подстановкой. В конце цепных замен все пробелы удаляются.

Грязное выражение echo -$_{1..78}|tr -d '-' в первой строке просто создает 78 пробелов. Вы можете просто заменить его длинной строкой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...