Замена символа-разделителя в поле

Algunas suscripciones de productos de Red Hat adquiridas antes de diciembre de 2017 incluían Oracle Java SE, y seguirán recibiendo soporte hasta fines de noviembre de 2018. Las suscripciones adquiridas después de diciembre de 2017 ya no incluyen Oracle Java SE y no se pueden usar. Tal como lo entiendo, esto es lo que se entiende en este caso por "mantenimiento restringido" :, cubre paquetes que solo están disponibles para un subconjunto de suscripciones para un producto determinado, con un límite de tiempo.

Si tiene acceso a Oracle Java SE, sus suscripciones deberían haberse actualizado. Si ese no es el caso, debe comunicarse con el soporte técnico de Red Hat.

Consulte este artículo de la base de conocimientos para obtener más detalles.

(Solo hablo por mí mismo, como siempre.)

2
14.06.2019, 20:13
6 ответов
awk -F'|' -v OFS='|' 'NF == 6 {$4 = $4 " OR " $5; $5=$6; NF--} 1' file

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

Или GNU sed:

sed 's/|/|/5; ta; n; :a; s/|/ OR /4' file

Если есть 5 труб, замените 4-ю. Не работает с sed по умолчанию в MacOS --если точки с запятой заменены новыми строками, MacOS sed в порядке с этими командами (кажется, что имя метки должно сопровождаться новой строкой с производным от BSD -sed ).


Что делать, если имеется больше , чем 1 лишняя труба? Рассмотрим этот файл:

|time: 10:19 | Error: File not found| Condition: None | path: some
|time: 10:20 | Error: File not found| Condition: a|b | path: someh
|time: 12:34 | NO ERROR | Condition: a|b AND c|d AND e|f | path: nil

Расширить решение sed несложно :добавить «переход -если»

sed ':b; s/|/|/5; ta; n; :a; s/|/ OR /4; tb' file

awk становится немного многословнее:

awk -F'|' -v O FS='|' '{
    while (NF > 5) {
        $4 = $4 " OR " $5
        for (i = 5; i < NF; i++)
            $i = $(i+1)
        NF--
    }
    print
}' file
4
27.01.2020, 21:55

Проверьте это:

sed 's/Condition:[ ]*\([a-zA-Z]*\)|\([a-zA-Z]*\)/Condition: \1 OR \2/g' your_file

Предполагая, что aи bявляются алфавитными.

1
27.01.2020, 21:55

Скрипт Python3. Разбивает CSV-файл на список, определяемый разделителем '|' а затем соединить поля, если есть лишнее, и оно начинается со слова «Условие :»

import csv

for line in list(csv.reader(open('filename', 'r'), delimiter='|')):
    if len(line) > 5 and line[3].lstrip().startswith('Condition:'):
        print('|'.join(line[:3] + [line[3] + ' OR ' + line[4]]+line[5:]))
    else:
        print('|'.join(line))
0
27.01.2020, 21:55

С помощью GNU sedвы можете сделать это, как показано:

 $ sed -e '
   s/|/\n/4g
   s/\(.*\)\n/\1|/
   s/\n/ OR /g
 ' inp


 $ perl -lpe '1 while s/Condition:.*\K\|(?! path:)/ OR /' inp


 $ perl -lpe '
   /Condition:.*?(?=\|)/g;
   s/\G.(.*?)(?=\|)/ OR $1/g;
 ' inp

$ perl -F'[|]' -pale '
     $_ = join "|", @F[0..2], join(" OR ", @F[3..$#F-1]), $F[-1] if @F > 5;
 ' inp

 $ perl -lpe '
     my($dlim, $pos_f3, $pos_f4, $knt) = qw/|/;
     $pos_f3 = 1+index($_,$dlim,$pos_f3) while ++$knt < 4;
     $pos_f4 = rindex($_,$dlim);
     s/\Q$dlim\E/ OR /g for substr $_, $pos_f3, $pos_f4-$pos_f3;
 ' inp
0
27.01.2020, 21:55

Общий подход к изменению целевого поля, которое может содержать разделители,:

/(match the fields before the target)(.*)(match the fields after the target)/ {
   modify the target which is the middle section, the string matching the ".*"
}

напр. с GNU awk для соответствия 3-го аргумента():

$ awk '
    match($0,/(([^|]*[|]){3})(.*)([|][^|]*)/,a) {
        gsub(/[|]/," OR ",a[3])
        $0 = a[1] a[3] a[4]
    }
1' file
|time: 10:19 | Error: File not found| Condition: None | path: some
|time: 10:20 | Error: File not found| Condition: a OR b | path: some

и, учитывая более интересный вклад, показанный в ответе Гленна:

$ cat file
|time: 10:19 | Error: File not found| Condition: None | path: some
|time: 10:20 | Error: File not found| Condition: a|b | path: someh
|time: 12:34 | NO ERROR | Condition: a|b AND c|d AND e|f | path: nil

$ awk '
    match($0,/(([^|]*[|]){3})(.*)([|][^|]*)/,a) {
        gsub(/[|]/," OR ",a[3])
        $0 = a[1] a[3] a[4]
    }
1' file
|time: 10:19 | Error: File not found| Condition: None | path: some
|time: 10:20 | Error: File not found| Condition: a OR b | path: someh
|time: 12:34 | NO ERROR | Condition: a OR b AND c OR d AND e OR f | path: nil

С любым awk было бы:

$ awk '
    match($0,/(([^|]*[|]){3})/) {
        a[1] = substr($0,RSTART,RLENGTH)
        rest = substr($0,RSTART+RLENGTH)
        match(rest,/[|][^|]*$/)
        a[3] = substr(rest,1,RSTART-1)
        a[4] = substr(rest,RSTART,RLENGTH)
        gsub(/[|]/," OR ",a[3])
        $0 = a[1] a[3] a[4]
    }
1' file
|time: 10:19 | Error: File not found| Condition: None | path: some
|time: 10:20 | Error: File not found| Condition: a OR b | path: someh
|time: 12:34 | NO ERROR | Condition: a OR b AND c OR d AND e OR f | path: nil
0
27.01.2020, 21:55

Из вашего примера кода определяющее правило, по-видимому, заключается в том, что везде, где |есть , не ограниченное с обеих сторон пробелом, вы хотите, чтобы оно стало OR, так что просто

sed -E 's/([^ ])\|([^ ])/\1 OR \2/g' test
0
27.01.2020, 21:55

Теги

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