Захватить раздел текста, где находится строка

Я обычно использую цикл while для чего-то подобного, с петлей for, вложенной внутри:

with open(filename) as f_in:
  while True:
    line = f_in.readline().strip()
    if not line:
      break
    if line == "text":
      data = [f_in.readline().strip() for i in range(15) if i in [2, 11, 13, 14]]

Это позволяет избежать загрузки всего файла перед его обработкой и особенно полезно, если у вас могут быть дополнительные строки между вашими сегментами данных, которые вам не нужно загружать, но они будут работать только в том случае, если не накладываются сегменты.

Обратите внимание, что этот код будет лишать ведущие и конечные пробелы из линии. Если вы хотите удалить только пробелы, вы можете использовать rstrip(). Если вы хотите вообще не менять строку, вы можете попробовать совпадение с префиксом startswith() или просто включить символ новой строки в ваше состояние.

0
задан user3299633 20 January 2019 в 19:47
поделиться

4 ответа

Я предполагаю, что ваш файл запросов будет выглядеть так, как показано ниже. Пожалуйста, попробуйте это решение 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 ' 

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

[110]

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

$ perl -0777 -ne ' while( /(# Query.+?)(# Query.+|\Z)/smg ) { $x=$1 ; 

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

[110]

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

[111]="$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' $
.="# Query "; while( /(# Query.+?)(# Query.+)/smg ) { $x=$1 ;

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

[110]

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

$ perl -0777 -ne ' while( /(# Query.+?)(# Query.+|\Z)/smg ) { $x=$1 ; 

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

[110]

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

[111]="$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' $
="$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 ; 

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

[110]

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

[111]="$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' $
0
ответ дан stack0114106 20 January 2019 в 19:47
поделиться

Окончательное рабочее решение:

# 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
ответ дан user3299633 20 January 2019 в 19:47
поделиться

Это может сработать для вас (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 и, если ее нет, напечатайте коллекцию. Все остальные строки не будут напечатаны.

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

sed -n '/^# Query [0-9]*:/{:a;$!{N;/^\s*$/M!ba};/Hosts.*127-0-0-1/I!p}' file
0
ответ дан potong 20 January 2019 в 19:47
поделиться

Учитывая, что 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
ответ дан Tiw 20 January 2019 в 19:47
поделиться
Другие вопросы по тегам:

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