Ich habe eine Textdatei ähnlich dieser:
line 1
line 2A
line 3
line 4A
line 5
Ich möchte von „Zeile 2A“ bis zum Ende der Datei „greppen“, ungefähr so
cat file.txt|some_grep "line 2A"
Außerdem möchte ich von „Zeile 2A“ zur nächsten Zeile „greppen“, die „A“ enthält, ungefähr so
cat file.txt| some_grep "A"
Ich möchte, dass dies ausgedruckt wird:
line 2A
line 3
line 4A
Welcher Befehl kann mir dabei helfen?
Antwort1
(aus dem Kommentar erweitert)
awk
verfügt über die Fähigkeit, Linienbereiche auszuwählen, die diesem Bedarf perfekt entsprechen, dabeschrieben im GNU-awk (gawk)-Handbuch. (Diese Funktion funktioniert in anderen awk
s, aber das gawk
Handbuch ist leicht zu verlinken.)
awk '/line 2A/,0'
druckt Zeilen, beginnend mit der ersten übereinstimmenden Zeile line 2A
und weiter bis zum Ende der Eingabe, da 0
diese Bedingung niemals erfüllt ist.
awk '/line 2A/,/A/&&!/line 2A/'
beginnt mit dem Drucken mit einer Zeile, die übereinstimmt, line 2A
und stoppt nach einer Zeile, die übereinstimmt A
, aber NICHT übereinstimmt line 2A
(und daher nicht dieselbe Zeile wie die Startzeile sein kann). Es beginntwiederauf einenanschließend line 2A
und so weiter. Wenn Sie dies verhindern möchten, gibt es etwas kompliziertere Möglichkeiten.
Wenn die Stoppzeilen vor immer ein anderes Zeichen als haben, kann dies vereinfacht werden, 2
indem nach einer Zeile gestoppt wird, die einem beliebigen Zeichen außer 2 gefolgt von A entspricht. Sie möchten vielleicht eine Variation hiervon, z. B. bei jedem einstelligen A ungleich 2A anzuhalten, aber nicht bei anderen As wie ; dafür könnte die Stoppbedingung sein .A
awk '/line 2A/,/[^2]A/'
WHAT
,/line [013-9]A/
Antwort2
Ich möchte von „Zeile 2A“ bis zum Ende der Datei „greppen“:
sed -n '/2A/,$p'
- -n:
sed
Standardausgabe unterdrücken - /2A/ : Ausgabezeilen ab der ersten Zeile, die "2A" enthält
- $: bis zum Ende der Datei
Ich möchte von „Zeile 2A“ zur nächsten Zeile „greppen“, die „A“ enthält:
sed -n '/2A/,/A/p'
- /A/: Ausgabe, bis eine Zeile „A“ enthält
Ich möchte von der ersten Zeile, die „A“ enthält, zur nächsten „greppen“:
printf "/A\n.+1,/A/p\nq" | ed -s
$ > foo echo "line 1
line 2A
line 3
line 4A
line 5"
$ sed -n '/2A/,$p' foo
line 2A
line 3
line 4A
line 5
$ sed -n '/2A/,/A/p' foo
line 2A
line 3
line 4A
$ printf "/A\n.+1,/A/p\nq" | ed -s foo
line 2A
line 3
line 4A
Antwort3
Ich denke, die beste Methode ist die Verwendung grep
in Kombination mit cut
und tail
. Verwenden Sie zunächst grep, um die Zeile zu erhalten, in der sich der gewünschte String befindet ( -n
um die Zeilennummer auszugeben; -m 1
um die Suche nach der ersten Übereinstimmung zu beenden):
grep -n -m 1 "somestring" filename.txt
Dies gibt die Zeilennummer und den String selbst aus. Um den String wegzuschneiden, verwenden wir cut ( -f1
: erstes Feld ausgeben; -d:
als Trennzeichen ":" verwenden):
grep -n -m 1 "somestring" filename.txt | cut -f1 -d:
Als nächstes verwenden wir die Ausgabe dieses Befehls als Parameter in tail. Normalerweise druckt tail die letzten k Zeilen, aber mit druckt -n +k
tail ab Zeile k. Der Gesamtbefehl lautet:
tail -n +`grep -n -m 1 "somestring" filename.txt | cut -f1 -d:` filename.txt
Um die Zeilen bis auszugeben, somestring
verwenden Sie head
anstelle von tail
und -n -#
anstelle von -n +#
. Sie können auch beides kombinieren, um die Zeilen von einer Zeichenfolge bis zur nächsten zu erhalten.
Antwort4
Bitte versuchen Sie den folgenden Code -
sed -n '6,$p' infile