Как я могу получить слова между первыми двумя экземплярами текста / образца? - PullRequest
6 голосов
/ 15 мая 2019

Введите:

===================================
v2.0.0

Added feature 3
Added feature 4
===================================
v1.0.0

Added feature 1
Added feature 2
===================================

Вывод, который я хочу:

v2.0.0

Added feature 3
Added feature 4

Я пытался это , но он получает first equals (=) и LAST equals (=), в то время как я хочу получить это ПЕРВЫЙ ДВА равняется (=)

Ответы [ 6 ]

3 голосов
/ 15 мая 2019

С GNU awk для нескольких символов RS:

$ awk -v RS='(^|\n)=+\n' 'NR==2' file
v2.0.0

Added feature 3
Added feature 4

С любым другим awk эквивалент будет длиннее:

$ awk '
    /^=+$/ { prt(); next }
    { rec=rec $0 ORS }
    END { prt() }
    function prt() { if (++nr==2) printf "%s", rec; rec="" }
' file
v2.0.0

Added feature 3
Added feature 4

Обратите внимание, что вышеприведенное будет работать для печати любого количества записей, а не только 2-й, просто путем изменения 2 на любой номер записи, который вы хотите распечатать, и вы можете тривиально добавлять / изменять условия, например, только печать записи, если она содержит некоторые строка вместо или в дополнение к основанным на номере записи, например распечатать 17-ю запись, если она содержит foo:

awk -v RS='(^|\n)=+\n' 'NR==17 && /foo/' file

Объяснение: Ваши записи разделены === строками, поэтому установите разделитель записей RS на регулярное выражение, соответствующее этому описанию, а затем просто напечатайте запись, когда количество записей (NR) достигнет нужного вам числа. то есть 2 (потому что перед первой строкой === есть нулевая запись).

3 голосов
/ 15 мая 2019

Не могли бы вы попробовать тоже.

awk '/^=/{count++;next} count>=2{exit} {print}'  Input_file
3 голосов
/ 15 мая 2019

Вот еще один в GNU sed:

$ sed -n '/^=\+$/,//{//!p;b};q' file
v2.0.0

Added feature 3
Added feature 4
  • /^=\+$/,// является сокращением для /^=\+$/,/^=\+$/, оно выбирает строки между двумя строками, включающими знаки равенства включительно, и для этих строк выполняются команды между следующими фигурными скобками,
  • //!p является сокращением для /^=\+$/!p, это означает, что если входящая строка не одна из тех, которые состоят только из = s, выведите ее,
  • b означает переход к концу цикла (то есть пропуск q),
  • q для выхода из sed после печати выбранных строк.

Следующая версия будет работать с all POSIX-совместимыми seds, но выглядит в 2 раза более загадочно:

sed -n -e '/^=\{1,\}$/,//{//!p;b' -e '}' -e 'q' file

Обратите внимание, что они не будут работать, если на входе есть две последовательные все = строки.

3 голосов
/ 15 мая 2019

Вот один в awk:

$ awk '/^=+$/{f=!f;if(f==1)next;else if(f==0)exit}f' file
v2.0.0

Added feature 3
Added feature 4

В красивой печати:

$ awk '/^=+$/ {     # at ===...
    f=!f            # flag state is flipped
    if(f==1)        # if its one (first ===...)
        next        # next record
    else if(f==0)   # if zero (second ===...)
        exit        # nothing more to do yeah
}
f' file             # print
1 голос
/ 15 мая 2019

Это может работать для вас (GNU sed):

sed -n '/^=\+$/{:a;n;//q;p;ba}' file

Использовать явную печать, установив параметр -n, это означает, что строки будут напечатаны только командой p или P.

При обнаружении строки, содержащей все символы =, извлеките следующую строку, и, если она содержит такое же регулярное выражение, закройте файл.В противном случае выведите текущую строку и повторите.

1 голос
/ 15 мая 2019

Возможно, более чистое решение GNU sed:

sed -E '0,/^={35}$/d; //Q'

Или, если вас устраивает более простое регулярное выражение, предложенное в других ответах:

sed -E '0,/^=+$/d; //Q'

Дальнейшее объяснение:

  • Регулярное выражение (расширенное примечание -E) /^={35}$/ соответствует строке, аналогичной вашей, которая состоит ровно из 35 знаков равенства.(Альтернативное регулярное выражение /^=+$/ соответствует строке, состоящей из одного или нескольких знаков равенства.)

  • Команда 0,/^={35}$/d выбирает все строки от начала файла до первого появленияшаблон и удаляет.

  • Выражение // заставляет регулярное выражение sed использовать по умолчанию последнее регулярное выражение, которое использовалось как часть адреса или команды s///.

  • Команда Q - это расширение GNU, которое вызывает выход sed без печати. ​​

Тестирование:

# test.sh

cat > FILE <<EOF
other
text
===================================
v2.0.0

Added feature 3
Added feature 4
===================================
v1.0.0

Added feature 1
Added feature 2
===================================
EOF

gsed -E '0,/^={35}$/d; //Q' FILE

Вывод:

▶ bash test.sh 
v2.0.0

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