Как я передаю определенные части файла в другой файл?

У меня есть 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

Справка!

1
задан 5 December 2018 в 01:04

1 ответ

Получение довольного между именованными блоками текста

Позволяет адресу, получая содержание внутри 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
2
ответ дан 7 December 2019 в 13:20

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

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