Это текст:
* Tue This is the first line
– info 1
– info 2
– info 3
* Wed This is not to be included
Вывод этого текста должен быть таким:
* Tue This is the first line
– info 1
– info 2
– info 3
ПРИМЕЧАНИЕ: Я пробовал awk и sed, но не смог найти свой вывод. Проблема в том, что START и END - это одинаковые '*' (звездочка), и первый из них должен быть включен в вывод.
Сохраните образец текста в переменной:
$ SAMPLE=$(cat <<EOF
* Tue This is the first line
– info 1
– info 2
– info 3
* Wed This is not to be included
* Tue This is the first line
– info 1
– info 2
– info 3
* Wed This is not to be included
EOF
)
Используйте awk
, чтобы обработать $ SAMPLE
:
$ awk '{if($1~"\*"){if(p==1){p=0;next}else{p=1}}if(p==1){print $0}}' <<<"$SAMPLE"
* Tue This is the first line
– info 1
– info 2
– info 3
* Tue This is the first line
– info 1
– info 2
– info 3
РЕДАКТИРОВАТЬ
Как было предложено в комментариях, существует удивительно элегантное решение awk
:
$ awk '/^\*/{p=!p};p' <<<"$SAMPLE"
* Tue This is the first line
– info 1
– info 2
– info 3
* Tue This is the first line
– info 1
– info 2
– info 3
Как это работает:
/ ^ \ * / {p =! P};
- это будет измените значение p
на 1
и 0
. Он станет 1
при первом обнаружении регулярного выражения / ^ \ * /
. При втором обнаружении p
станет 0
и так далее.
p
- это эквивалент p {print}
. Поскольку print
является действием по умолчанию в awk
, оно всегда будет печатать, когда предварительное условие оценивается как значение true
, в данном случае, когда p
становится 1
.
Надеюсь, я правильно понимаю. Этот сценарий удалит все из строки, начиная со второго *
до конца буфера, создав желаемый результат из примера:
sed -n 'H;1h;$x;$s/\(\*[^*]*\)\n\*.*$/\1/p'
Пояснение добавить все строки ( H
) в буфер удержания. Для удержания последнего обмена строкой и буфера шаблонов ( $ x
), поэтому у вас есть весь файл как один шаблон. В этом шаблоне сохраняемая часть устанавливается в \ (\)
и сохраняется ( \ 1
), в то время как все, начиная с новой строки с *
, удаляется.
Это соответствует вашему описанию, но если это не подходит для всех возможных примеров, вы можете изменить сценарий.
perl -lne 'if ( m?^\*? ... m?^\*? ) { print if !// || !$a++ }'
sed -e '
/^\*/!d
:loop
$q; N
/\n\*/!bloop
s/\(.*\)\n.*/\1/;q
'
sed -e '
/^\*/!d
:loop
n
//!bloop
Q
'