Как напечатать последнюю строку каждой группы для длинного списка строк в командной строке, используя awk или любой? - PullRequest
0 голосов
/ 09 ноября 2019

Используя grep для многих файлов в bash, каждый файл показывает несколько строк. Поэтому я хочу получить одну последнюю строку для каждого файла. После использования grep вывод будет выглядеть следующим образом:

- re0_400.out:  18 F= -.36810451E+02 E0= -.36810451E+02  d E =-.133023E-01
- re0_400.out:  19 F= -.36810451E+02 E0= -.36810451E+02  d E =-.133024E-01
- re0_400.out:  20 F= -.36797147E+02 E0= -.36797147E+02  d E =0.137473E-05
- re0_400s.out:   1 F= -.18286638E+02 E0= -.18286638E+02  d E =-.182866E+02
- re0_400s.out:   2 F= -.18277347E+02 E0= -.18277347E+02  d E =0.929017E-02
- re0_400s.out:   3 F= -.18293043E+02 E0= -.18293043E+02  d E =-.640539E-02
- re0_400s.out:   4 F= -.18293044E+02 E0= -.18293044E+02  d E =-.640678E-02
- re0_450.out:   1 F= -.36767212E+02 E0= -.36767212E+02  d E =-.367672E+02
- re0_450.out:   2 F= -.36750221E+02 E0= -.36750221E+02  d E =0.169913E-01
- re0_450.out:   3 F= -.36780151E+02 E0= -.36780151E+02  d E =-.129382E-01
- re0_450.out:   4 F= -.36780151E+02 E0= -.36780151E+02  d E =-.129384E-01

Пробный код:

awk '$1=="BB" && $2>1 {print f} {f=$1}' a.txt

Это код ( Печать предыдущей строки, если условие выполнено ) чтобы напечатать предыдущую строку, когда поле соответствует условию. Но в моем случае мне нужно сравнить одни и те же поля в две строки.

Результаты должны быть

- re0_400.out:  20 F= -.36797147E+02 E0= -.36797147E+02  d E =0.137473E-05
- re0_400s.out:   4 F= -.18293044E+02 E0= -.18293044E+02  d E =-.640678E-02
- re0_450.out:   4 F= -.36780151E+02 E0= -.36780151E+02  d E =-.129384E-01

Как получить этот результат в bash с помощью awk или любой команды в оболочке?

1 Ответ

1 голос
/ 09 ноября 2019

Не могли бы вы попробовать следующее (здесь я считал, что ваш Input_file имеет - хэши, показанные вами в примерах, если у вас их нет, попробуйте изменить $2 на $1 в следующем коде).

awk '
!a[$2]++{
  b[++count]=$2
}
{
  c[$2]=$0
}
END{
  for(i=1;i<=count;i++){
    print c[b[i]]
  }
}
'   Input_file

Вывод будет следующим:

- re0_400.out:  20 F= -.36797147E+02 E0= -.36797147E+02  d E =0.137473E-05
- re0_400s.out:   4 F= -.18293044E+02 E0= -.18293044E+02  d E =-.640678E-02
- re0_450.out:   4 F= -.36780151E+02 E0= -.36780151E+02  d E =-.129384E-01


Объяснение: Добавление подробного объяснения для приведенного выше кода.

awk '                         ##Starting awk program from here.
!a[$2]++{                     ##Checking condition if $2 is NOT present in array a then put $2 in array a, so this condition will make sure each filename is coming only once in arrays.
  b[++count]=$2               ##Creating an array named b whose index is variable count with increment number 1 each time and its value is $2 of current line.
}                             ##Closing BLOCK for  this condition here.
{
  c[$2]=$0                    ##Creating an array named c whose index is $2 and value is $0. Since OP needs ALWAYS the LATEST line for files so this will keep over-writing the lines values of same file names and maintain latest file name value only.
}
END{                          ##Starting END section of this awk program here.
  for(i=1;i<=count;i++){      ##Starting a for loop from i=1 to till value of count, where variable count actually having number of file names($1 or $2, $1 without hashes in your Input_file and with hashes $2).
    print c[b[i]]             ##We are printing array c whose index is b[i] which will be having exact line value.
  }                           ##Closing for loop BLOCK here.
}
'  Input_file                 ##Mentioning Input_file name here.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...