Используйте
"${*:2}"
вместо
"${@:2}"
$ @
и $ {x [@]}
и их варианты, расширяются до одного «слова» на элемент в массиве в кавычках. $ *
(и $ {x [*]}
) расширяются до одного слова со всеми элементами, соединенными вместе с использованием первого символа $ IFS
.
Если они вообще не цитируются, обе версии подвергаются разделению на слова и создают несколько разделенных слов везде, где встречается любой из символов IFS
.
Ваш файл содержит символы "возврата каретки". В 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
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
, нарушит эту логику. Если вы хотите это в скрипте 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]))