Как я могу отредактировать диапазон текста между 2 символами? awk, sed, regex

Используя "*" символ, (не должен быть то, что один, любой специальный символ сделает для указания), как может, я редактирую текст от этого:

*berry
straw
rasp
blue
boysen
*
blahblah
blahblah
blahblah
*berry
straw
blue
*
blah
*table
vege
pingpong
*

К этому:

strawberry
raspberry
blueberry
boysenberry
blahblah
blahblah
blahblah
strawberry
blueberry
blah
vegetable
pingpongtable

Каждый символ после первой звездочки соответствия будет помещен в каждую строку, пока 2-е соответствие звездочки не будет найдено.

Кто-либо вовлекает, как я могу пойти об этом? (sed или awk был бы предпочтен, но если можно думать иначе, стреляйте в меня код!)

Я знаю, как удалить все строки, содержащие звездочку, это - просто символьная первая часть размещения, не может думать

6
задан 24 April 2015 в 19:18

5 ответов

Это awk код мог быть достаточно:

awk -F'*' 'NF == 2 {label = $2; next} {$0 = $0 label} 1'

Сломать его:

  • Использовать * как разделитель полей. Таким образом, мы можем просто исследовать количество полей (NF) определить, достигнуты ли начало или конец блока.
  • Когда существует два поля, мы сохраняем второе поле в label и продолжите к следующей строке.
  • С того времени мы добавляем это label к текущей строке, и затем печатают. Если маркировка пуста, мы вне блока и нет никакого эффекта. В противном случае мы получаем необходимый вывод.
12
ответ дан 23 November 2019 в 07:13

В sed, Вы могли скопировать "специальную" строку в пространство хранения прежде, чем удалить его

sed -e '/^\*/{h;d;}'

и затем добавить пространство хранения к каждому последующему пространству шаблона, заменив получающуюся новую строку и символ маркера

    -e '{G;s/\n\*//;}'

Тестирование его с Вашими данными,

$ sed -e '/^\*/{h;d;}' -e '{G;s/\n\*//;}' file
strawberry
raspberry
blueberry
boysenberry
blahblah
blahblah
blahblah
strawberry
blueberry
blah
vegetable
pingpongtable

Примечание: это не останавливается, когда это встречается со второй звездочкой; это делает точно то же, но это добавляет * сопровождаемый ничем - пока это не соответствует следующему *sometext.

8
ответ дан 23 November 2019 в 07:13

Через мой любимый Python...

with open('/path/to/the/file') as f:
    counter = False
    for line in f:
        if line.startswith('*') and not counter:
            m = line.strip().lstrip('*')
            counter = True
        elif line.startswith('*') and counter:
            counter = False    
        elif counter:
            if not line.startswith('*'):
                print(line.strip() + m)
        else:
            print(line.strip())  
3
ответ дан 23 November 2019 в 07:13

Прибыл сюда поздно. Вот другой python подход:

#!/usr/bin/env python2
with open('/path/to/file.txt') as f:
    for lines in f.read().split('*'):
        entries = lines.rstrip().split('\n')
        for i in range(1, len(entries)):
            print entries[i] + entries[0]
3
ответ дан 23 November 2019 в 07:13

Вот является Perl путем:

$ perl -lne '/^\*(.*)/ || print "$_$1"' file
strawberry
raspberry
blueberry
boysenberry
blahblah
blahblah
blahblah
strawberry
blueberry
blah
vegetable
pingpongtable

Объяснение

-n заставит Perl читать каждую строку входного файла, сохраняя его в специальной переменной $_, -l вызовет его к полосе i), запаздывающей новые строки (\n) от каждой строки и ii), добавляет новая строка к каждому вызову print. -e сценарий, который применяется к каждой строке.

  • /^\*(.*)/ : строки соответствия, которые запускаются со звездочки и сохраняют все после звездочки как $1 (это - то, что круглые скобки делают).

  • || print "$_$1"' : || логическое OR. Поэтому print будет только выполняться, если текущая строка не запускалась со звездочки. Если так, мы печатаем текущую строку ($_) наряду с чем в настоящее время сохраняется как $1 (шаблон после звездочки).


Как обычно, существует много способов сделать это. Глупый и неэффективный, но тот, который выделяет возможности обработки строк оболочки:

$ while read line; do 
    [[ $line =~ ^\* ]] && pat="${line#\*}" || printf "%s%s\n" "$line" "$pat"; 
  done < file
strawberry
raspberry
blueberry
boysenberry
blahblah
blahblah
blahblah
strawberry
blueberry
blah
vegetable
pingpongtable

Объяснение

  • while read line; do ... ; done < file : это - классик while цикл, который считает каждую строку входного файла file и сохраните его как $line.
  • [[ $line =~ ^\* ]] && pat="${line#\*}" : если строка запускается с *, удалите все после этого (это что ${line#\*} для получения дополнительной информации, действительно видит здесь), и сохраните его как $pat. *|| printf "%s%s\n" "$line" "$pat"; : если предыдущая неудавшаяся команда (так, строка не запускается со звездочки), распечатайте строку и текущее значение $pat.

7
ответ дан 23 November 2019 в 07:13

Другие вопросы по тегам:

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