Как можно более четко реализовать пары строк слияния скрипта "grep | sed | awk"? - PullRequest
0 голосов
/ 01 мая 2018

У меня есть небольшой скрипт для извлечения определенных данных и небольшой очистки выходных данных. Это кажется слишком грязным, и мне интересно, можно ли немного урезать сценарий.


  • Входной файл содержит пары строк - имена, за которыми следуют цифры.
  • Пары линий, числовое значение которых не находится в диапазоне от 80 до 199, следует отбрасывать.
  • Пары могут иногда, но не всегда, предшествовать или сопровождаться пустыми строками, которые следует игнорировать.

Пример входного файла:

al12t5682-heapmemusage-latest.log
38

al12t5683-heapmemusage-latest.log
88
al12t5684-heapmemusage-latest.log
100
al12t5685-heapmemusage-latest.log
0

al12t5686-heapmemusage-latest.log
91

Пример / требуемый результат:

al12t5683 88
al12t5684 100
al12t5686 91

Текущий скрипт:

grep --no-group-separator -PxB1 '([8,9][0-9]|[1][0-9][0-9])' inputfile.txt \
  | sed 's/-heapmemusage-latest.log//' \
  | awk '{$1=$1;printf("%s ",$0)};NR%2==0{print ""}'

Пример дополнительного ввода

al14672-heapmemusage-latest.log
38

al14671-heapmemusage-latest.log
5

g4t5534-heapmemusage-latest.log
100

al1t0000-heapmemusage-latest.log
0
al1t5535-heapmemusage-latest.log
al1t4676-heapmemusage-latest.log
127

al1t4674-heapmemusage-latest.log
53

A1t5540-heapmemusage-latest.log
54

G4t9981-heapmemusage-latest.log
45

al1c4678-heapmemusage-latest.log
81

B4t8830-heapmemusage-latest.log
76

a1t0091-heapmemusage-latest.log
88

al1t4684-heapmemusage-latest.log
91

Дополнительный пример ожидаемого результата:

g4t5534 100
al1t4676 127
al1c4678 81
a1t0091 88
al1t4684 91

Ответы [ 4 ]

0 голосов
/ 01 мая 2018

с гну сед

sed -E '
N
/\n[8-9][0-9]$/bA
/\n1[0-9]{2}$/!d
:A
s/([^-]*).*\n([0-9]+$)/\1 \2/
' infile
0 голосов
/ 01 мая 2018
perl -nle's/-.*//; $n=<>; print "$_ $n" if 80<=$n && $n<=199' inputfile.txt
0 голосов
/ 01 мая 2018

еще awk

$ awk -F- 'NR%2{p=$1; next} 80<=$1 && $1<=199 {print p,$1}' file

al12t5683 88
al12t5684 100
al12t5686 91

UPDATE

для разделителя записей пустой строки

$ awk -v RS= '80<=$2 && $2<=199{sub(/-.*/,"",$1); print}' file

al12t5683 88
al12t5684 100
al12t5686 91
0 голосов
/ 01 мая 2018

Подумайте о реализации этого в собственном bash, как показано ниже (что можно увидеть при работе с вашим вводом образца - включая спорадически присутствующие пустые строки) при http://ideone.com/Qtfmrr):

#!/bin/bash
name=; number=
while IFS= read -r line; do
  [[ $line ]] || continue                       # skip blank lines
  [[ -z $name ]] && { name=$line; continue; }   # first non-blank line becomes name
  number=$line                                  # second one becomes number
  if (( number >= 80 && number < 200 )); then
    name=${name%%-*}                            # prune everything after first "-"
    printf '%s %s\n' "$name" "$number"          # emit our output
  fi
  name=; number=                                # clear the variables
done <inputfile.txt

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

См:

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