Решение для 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
Если интерполированные значения должны быть просто разнесены через равные промежутки, то это может сделать:
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
И нет, это не единственный способ «интерполировать».
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!