awk-интерполяция значений в столбце

Решение для sed (, например ), заключается в преобразовании каждой начальной и конечной строк в один символ, поэтому мы можем использовать регулярные выражения, которые избегают (отрицания )одного символа [^…].

Конвертировать в один символ (Предположим, что%(start )и#(end )не могут появиться в вашем файле, подробнее позже):

<<<infile sed 's/abstract =/%/g; s/},\n/#/g'

Затем мы можем выбрать (и стереть )от первого начального(%)символа до первого конечного(#)символа, следующего за:

sed 's/%[^#]*#//g'

[^#]требуется, чтобы сопоставление не было -жадным .

Поскольку некоторые символы-разделители могут все еще существовать, нам необходимо их восстановить.

sed 's/%/abstract =/g; s/#/},\n/g'    # assuming GNU sed.

И, конечно же, все вышеперечисленное нужно применять ко всему файлу, так как шаблоны могут появляться в разных строках. Итак, мы захватываем весь файл в пространство хранения:

sed 'H;1h;$!d;g;'

В одной полной командной строке:

 <infile sed 'H;1h;$!d;g;  s/abstract =/%/g; s/},\n/#/g;
                           s/%[^#]*#//g ;
                           s/%/abstract =/g; s/#/},\n/g'

Если выбранные символы могут существовать во входном файле, мы можем выбрать некоторые другие разделители, которые не будут существовать в ваших текстовых файлах.

Символы (байты )со значением 01и 02, которые называются SOH (начало заголовка )и STX (начало текста )в ASCII, являются "управлением символы», которые довольно редко встречаются в текстовых файлах. Чтобы их использовать, нам лучше создать сценарий оболочки:

 #!/bin/bash
 start=$'\1'
 end=$'\2'
 startpattern='abstract ='
 endpattern=$'},\\\n'         # The newline needs a `\` for sed to work.

 sed 'H;1h;$!d;g;
      s/'"$startpattern"'/'"$start"'/g;
      s/'"$endpattern"'/'"$end"'/g;
      s/'"$start"'[^'"$end"']*'"$end"'//g;
      s/'"$start"'/'"$startpattern"'/g;
      s/'"$end"'/'"$endpattern"'/g'  <infile
-1
19.03.2020, 16:44
2 ответа

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

awk '
  NF > 1 {
    if(i++){ d=($2-s)/i; for(j=1; j<i; j++) printf "%s\t%.2f\n", a[j], s+j*d }
    s=$2; i=0; printf "%s\t%.2f\n", $1, $2
    next
  }
  { a[++i] = $1 }
' file

И нет, это не единственный способ «интерполировать».

2
28.04.2021, 23:20
awk '
  BEGIN {split("",A)}
  $2 == "" {
    A[length(A)] = $1
    # print $0, length(A)
  }
  $2 != "" {
    if (length(A) > 0) {
      I = ( $2 - P2 ) / (length(A) + 1)
      for(X=0; X<length(A); X++) {
        print "<" A[X] " "  (P2 + I * (X+1)) ">"
      }
      split("",A)
    }
    print  "!" $1 " " $2 "!"
    P1=$1; P2=$2
  }
  END {}
'

дает

!542 701.00!
<789 702>
!971 703.00!
!123 708.00!
<879 710>
<785 712>
<974 714>
!101 716.00!
0
28.04.2021, 23:20

Теги

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