Совместите patternA и распечатайте его только при совпадении patternB, включая следующую строку

Используйте

"${*:2}"

вместо

"${@:2}"

$ @ и $ {x [@]} и их варианты, расширяются до одного «слова» на элемент в массиве в кавычках. $ * $ {x [*]} ) расширяются до одного слова со всеми элементами, соединенными вместе с использованием первого символа $ IFS .

Если они вообще не цитируются, обе версии подвергаются разделению на слова и создают несколько разделенных слов везде, где встречается любой из символов IFS .

4
26.08.2018, 10:52
3 ответа

Ваш файл содержит символы "возврата каретки". В Unix их лучше удалить. Чтобы напечатать последовательность команд, которые вы разместили, напечатайте (с удаленным возвратом каретки ), попробуйте:

awk '{gsub(/\r/,"")}
     /mod/          { a = $0 }
     /search_string/{ if(a!=""){print(a);a=""}
                      print;getline;print
                    }
    ' infile

Или в виде одного -вкладыша:

$ awk '{gsub(/\r/,"")}/mod/{a=$0}/search_string/{if(a!=""){print(a);a=""}print;getline;print}' infile

mod start3  
 search_string yada yada  
 hello  
 search_string yada yada  
 bye  
mod start4  
 search_string baba baba  
 this too  

Поскольку в (GNU )awk можно использовать многосимвольный разделитель записей, мы можем установить разделитель записей на modи печатать только те записи, которые содержат search_string. printf требуется для восстановления исходной записи.

Чтобы распечатать то, что вы разместили как «Ожидаемый результат», попробуйте:

awk '/search_string/{printf("mod%s", $0)}' RS=mod infile
2
27.01.2020, 20:52
awk '
   $0 ~ /mod/ { md=$0 }
   $0 ~ /search_string/ { if(md!="") { print md }; md="" ; print; getline; print }
   '

Пояснение:

  • Строка, содержащая mod, сохраняется как md.
  • Строка, содержащая search_string, запускает печать ранее сохраненного md, самой строки и следующей строки.
  • if(md!="")и md=""предназначены для того, чтобы убедиться, что вы не получаете дублированные строки mod, когда в вашем примере )многоsearch_string-под однимmod(mod start3.

Примечание:

  • Строка, содержащая как mod, так и search_string, нарушит эту логику.
4
27.01.2020, 20:52

Если вы хотите это в скрипте Python:

# Read file into memory.
with open('myfile.txt') as f:
    lines = [line.rstrip() for line in f]

# Loops through lines backwards, looking for string and optionally mod.
output_lines = list()
find_mod = False
for i, line in enumerate(lines[::-1]):
    if 'search_string' in line:
        output_lines.append(lines[::-1][i-1])
        output_lines.append(lines[::-1][i])
        find_mod = True
    elif find_mod and 'mod' in line:
        output_lines.append(lines[::-1][i])
        find_mod=False

print("\n".join(output_lines[::-1]))
0
27.01.2020, 20:52

Теги

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