Захватить раздел текста, где находится строка - PullRequest
0 голосов
/ 19 января 2019

У меня есть текстовый файл, который выглядит так:

# Query 1:
.
.
.
# Hosts ip-127-0-0-1
.
.
.

# Query 2:
.
.

В моем файле может быть несколько запросов; Я хочу извлечь информацию только тогда, когда мой ip НЕ является определенным значением.

Например, здесь я хочу захватить, начиная с «# Query 1» до пробела прямо перед тем, где написано «# Query 2» - однако мне нужно делать это ТОЛЬКО, если Hosts ip НЕ соответствует ip-127- 0-0-1. Это не точное совпадение, так как к ip-127-0-0-1 может добавляться другой текст, например ip-127-0-0-1.notusefultext

Я готов использовать awk, sed или python для решения этой проблемы.

Ответы [ 4 ]

0 голосов
/ 20 января 2019

Конечный рабочий раствор:

# Pull in isolated code block for each individual query and write to unique file.
TEMP='temp_file'
while read -r line; do
    if [[ $line =~ ^#[[:space:]]Query[[:space:]][0-9].* ]]; then
        new_query='1'
        ((counter++))
        echo "$line" > ${TEMP}_${counter}
    else
        new_query='0'
        echo "$line" >> ${TEMP}_${counter}
    fi
done < "${LONG_RUNNING_QUERIES}"

# Remove first file, as it only contains query statistics for all long running queries.
rm ${TEMP}_0

# For all files that don't contain the IP, group them together in one file.
QUERIES_TO_GRAB='master_file'
> $QUERIES_TO_GRAB
for i in $(ls -v1 temp_file_*); do
    match=$(grep "${IP_ADDY}" "$i")
    if [ -z "$match" ]; then
        cat $i >> $QUERIES_TO_GRAB
    fi
done
0 голосов
/ 19 января 2019

Учитывая, что anchors являются точными, и до # Query 1:,
нет ничего попробуйте это пожалуйста:

awk -v RS="# Query 2" 'FNR<2 && !/# Hosts ip-127-0-0-1/'

Судите сами, если хотите, чтобы только строки начинались с буквы в блоке, который вы описали:

awk -v RS="# Query 2" -F"\n" 'FNR<2 && !/# Hosts ip-127-0-0-1/{for (i=1;i<=NF;i++) if($i~ "^[A-Za-z]") print $i}'

Если условия несколько иные, пожалуйста, оставьте комментарий.

0 голосов
/ 19 января 2019

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

sed -n '/^# Query [0-9]*:/{:a;N;/^\s*$/M!ba;/Hosts.*127-0-0-1/I!p}' file

Используйте параметр sed * -n, чтобы печатать только явно.Сфокусируйтесь на любой строке, которая начинается # Query n*:, где n* означает ноль или более цифр (используйте [^:]*, если это совпадение слишком конкретное).Собирайте текущие и последующие строки до (и включая) пустой строки.Протестируйте коллекцию строк для строки 127-0-0-1 и, если ее нет, напечатайте коллекцию.Все остальные строки не будут напечатаны.

NB Коллекция включает в себя как строку запроса, так и пустую строку, это может быть не так, если последний запрос не имеет пустой строки в качестве последней строки файла,Это может быть улучшено улучшенной версией:

sed -n '/^# Query [0-9]*:/{:a;$!{N;/^\s*$/M!ba};/Hosts.*127-0-0-1/I!p}' file
0 голосов
/ 19 января 2019

Я предполагаю, что ваш файл запроса будет как ниже Пожалуйста, попробуйте это решение Perl

$ cat query_ip.txt
# Query 1:
select a b c from
tab
# Hosts ip-127-8-8-1
where a = '1'

# Query 2:
select a b c from
tab2
# Hosts ip-127-0-0-1
where a = '1'

# Query 3:
select a b c from
tab3
# Hosts ip-127-9-9-1
where a = '1'

$  perl -0777 -ne ' $_.="# Query "; while( /(# Query.+?)(# Query.+)/smg ) { $x=$1 ; $_="$2"; print $x if not $x=~/ip-127-0-0-1/ } ' query_ip.txt
# Query 1:
select a b c from
tab
# Hosts ip-127-8-8-1
where a = '1'

# Query 3:
select a b c from
tab3
# Hosts ip-127-9-9-1
where a = '1'

$

или попробуйте это.

$ perl -0777 -ne ' while( /(# Query.+?)(# Query.+|\Z)/smg ) { $x=$1 ; $_="$2"; print "$x\n" if not $x=~/ip-127-0-0-1/ } ' query_ip.txt
# Query 1:
select a b c from
tab
# Hosts ip-127-8-8-1
where a = '1'


# Query 3:
select a b c from
tab3
# Hosts ip-127-9-9-1
where a = '1'
$
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...