
Ich möchte alle Zeilen abrufen, die das Wort „search_string“ enthalten, sowie die Zeile danach und die Zeile davor, die mit „mod“ übereinstimmt.
Ich habe Folgendes versucht:
grep -n 'mod\|search_string' ip | grep --before 1 search_string> inter
grep -n --after 1 search_string ip >> inter
sort -t':' -k1,1n -u inter -o op
Gibt es einen besseren Weg?
Datei:
mod start1
some lines
mod start2
other lines
mod start3
many other lines
search_string yada yada
hello
many other lines
search_string yada yada
bye
mod start4
search_string baba baba
this too
mod start5
Erwartete Ausgabe :
mod start3
search_string yada yada
hello
search_string yada yada
bye
mod start4
search_string baba baba
this too
Antwort1
awk '
$0 ~ /mod/ { md=$0 }
$0 ~ /search_string/ { if(md!="") { print md }; md="" ; print; getline; print }
'
Erläuterung:
- Eine Zeile mit
mod
wird als gespeichertmd
. - Eine Zeile mit
search_string
löst das Drucken des zuvor gespeicherten ausmd
, der Zeile selbst und der nächsten Zeile. if(md!="")
undmd=""
sollen sicherstellen, dass Sie keine doppelten Zeilen erhalten , wenn sich viele -s unter einem einzigenmod
befinden ( in Ihrem Beispiel).search_string
mod
mod start3
Notiz:
- Eine Zeile, die sowohl
mod
als auch enthältsearch_string
, unterbricht diese Logik.
Antwort2
Ihre Datei enthält "Wagenrücklauf"-Zeichen. Unter Unix ist es besser, diese zu entfernen. Um die von Ihnen gepostete Befehlsfolge auszudrucken (ohne Wagenrückläufe), versuchen Sie Folgendes:
awk '{gsub(/\r/,"")}
/mod/ { a = $0 }
/search_string/{ if(a!=""){print(a);a=""}
print;getline;print
}
' infile
Oder als Einzeiler:
$ 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
Da es in (GNU) awk möglich ist, einen mehrstelligen Datensatztrenner zu verwenden, können wir den Datensatztrenner auf setzen mod
und nur Datensätze drucken, die enthalten search_string
. printf ist erforderlich, um den ursprünglichen Datensatz wiederherzustellen.
Um das auszudrucken, was Sie als „Erwartete Ausgabe“ gepostet haben, versuchen Sie Folgendes:
awk '/search_string/{printf("mod%s", $0)}' RS=mod infile
Antwort3
Wenn Sie dies in einem Python-Skript möchten:
# 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]))