У меня есть FILE1
NAMES START
Hi, How are you?
Good to see you
start
Aaron
Kyle
Robert
stop
Official use only
Stamps here
start
Riley
Gayle
stop
Bicycles here
United Pawns
start
Alex
Ford
Sergio
stop
NAMES STOP
Вот то, что я хочу сделать:
Если "ИМЕНА ЗАПУСКАЮТ" строку, присутствует, передайте содержание, которое каждый "запускает" и "останавливает", к новому FILE2, не учитывая запуск и останавливает сам в новом FILE2.
Таким образом, FILE2 должен быть похожим на это:
Aaron
Kyle
Robert
Riley
Gayle
Alex
Ford
Sergio
Справка!
Позволяет адресу, получая содержание внутри start..stop
блок, потому что это - главная задача.
grep
соответствующий строке инструмент, следовательно соответствование через несколько строк является трудным и grep
обычно не используется для такой задачи, хотя это не невозможно. Однако лучший подход в таком случае должен использовать awk
получить шаблоны между определенными строками и затем отфильтровать start
и stop
флаги:
$ awk '/start/,/stop/' input.txt | grep -v 'start\|stop'
Aaron
Kyle
Robert
Riley
Gayle
Alex
Ford
Sergio
Если мы хотим избавиться от конвейера, мы можем сделать:
# {print} is actually unnecessary, as default for awk is to print if
# expression evaluates to true, so it's enough to have
# awk '/start/{flag=1;next};/stop/{flag=0};flag' input.txt
$ awk '/start/{flag=1;next};/stop/{flag=0};flag == 1 {print}' input.txt
Aaron
Kyle
Robert
Riley
Gayle
Alex
Ford
Sergio
Существуют, конечно, другие методы, такой как sed
или perl
. Что касается grep
, часто предлагается использовать grep -Pzo
флаги, однако вероятно, из-за нескольких случаев start..block
это не работает правильно (только одно возвращенное соответствие):
$ grep -zPo --color 'start\n(.*\n.*)\nstop' input.txt
start
Riley
Gayle
stop
Ради простоты (хотя возможно awk
пример является самым простым) и постараться не иметь дело с regex шаблонами, мы можем также обратиться к основным сценариям:
#!/bin/bash
printline=0
while IFS= read -r line; do
# set flag for printing or not printing
case $line in
"start") printline=1; continue;;
"stop") printline=0; continue;;
esac
# check the flag
if [ "$printline" -eq 1 ]; then
printf "%s\n" "$line"
fi
# first positional parameter is the file we read
done < "$1"
И вот то, как сценарий работает:
$ chmod +x readblocks.sh
$ ./readblocks.sh input.txt
Aaron
Kyle
Robert
Riley
Gayle
Alex
Ford
Sergio
Если "ИМЕНА ЗАПУСКАЮТ" строку, присутствует, передайте содержание, которое каждый "запускает" и "останавливает", к новому FILE2, не учитывая запуск и останавливает сам в новом FILE2.
Ну, это справедливо grep 'NAMES START' input.txt
. Таким образом, мы можем проверить на это через
if grep -q 'NAMES START' input.txt; then
# whatever method you like goes here
fi
Рассмотрение примера, NAMES START
первая строка файла. Таким образом, мы можем также проверить на тот - проверяют первую строку, поскольку мы читаем файл, вместо того, чтобы открыть файл внутри if
оператор, предложенный выше.
При передаче содержания FILE2 - это просто добавляет > FILE2.txt
к исходной команде или сценарию Вы используете.
С этими предложениями, awk
команда становится:
$ awk 'NR==1 && $0 != "NAMES START"{exit};/start/{flag=1;next};/stop/{flag=0};flag' input.txt > FILE2.txt
И сценарий:
#!/bin/bash
printline=0
linecounter=0
while IFS= read -r line; do
linecounter=$((linecounter+1))
case "$line" in
"NAMES START") continue;;
*) exit 1;
esac
# set flag for printing or not printing
case $line in
"start") printline=1; continue;;
"stop") printline=0; continue;;
esac
# check the flag
if [ "$printline" -eq 1 ]; then
printf "%s\n" "$line"
fi
# first positional parameter is the file we read
done < "$1" > FILE2.txt