Suchen Sie die Zeilennummer, die das Muster enthält, mit einem benutzerdefinierten Regex-Trennzeichen


7

Wie im Beispiel versuche ich, Zeilennummern zu erhalten, die das Muster enthalten. Mein Muster enthält Schrägstriche, daher wollte ich ein benutzerdefiniertes Trennzeichen hinzufügen.

Dieser einfache funktioniert:

sed -n '/file/=' temp.txt

Die Verwendung des Trennzeichens für das Ersetzen von Zeichenfolgen funktioniert auch:

sed 's|file|gile|' temp.txt

Aber wenn ich dem ersten Beispiel ein Trennzeichen hinzufügen möchte, funktioniert dies nicht:

sed -n '|file /etc|=' temp.txt

Ich weiß, dass ich Schrägstrichen entkommen kann, aber ich würde es vorziehen, ein benutzerdefiniertes Trennzeichen hinzuzufügen. Irgendeine Idee, wie ich meinen Befehl reparieren kann?


sed -n '\|file /etc|='
Stéphane Chazelas

Vielen Dank! Was ich nach Ihrer Antwort gefunden habe: \% regexp% (Das% kann durch ein anderes einzelnes Zeichen ersetzt werden.) Dies entspricht auch dem regulären Ausdruck regexp, ermöglicht jedoch die Verwendung eines anderen Trennzeichens als /. Dies ist besonders nützlich, wenn der reguläre Ausdruck selbst viele Schrägstriche enthält, da er das mühsame Entweichen jedes / vermeidet. Wenn der reguläre Ausdruck selbst Trennzeichen enthält, muss jedes durch einen Backslash () maskiert werden.
jasiustasiu

Antworten:


9

Stéphane gab Ihnen die sedLösung:

sed -n  '\|file /etc|=' file 

Wenn Sie bereit sind, andere Tools zu verwenden, können Sie dies auch tun

grep -n 'file /etc' file

Dadurch wird auch die Zeile selbst gedruckt. Um die Zeilennummer allein zu erhalten, versuchen Sie Folgendes:

grep -n 'file /etc' file | cut -d: -f 1

Oder Sie können verwenden perl:

perl -lne 'm|file /etc| && print $.' file 

Oder awk:

awk '$0 ~ "file /etc" {print NR}'

Wenn Sie den Punkt verwenden, wird "etc" vor einem beliebigen Zeichen angezeigt. Verwenden Sie einen Schrägstrich, um genau zu sein.
Bis auf weiteres angehalten.

@ TennisWilliamson Ich habe keine Ahnung, warum ich in einigen davon einen Punkt verwendet habe. Muss ein Artefakt aus meinen Testläufen gewesen sein. Danke, behoben.
Terdon

4

In allen Kontextadressen müssen Sie das öffnende Trennzeichen umgehen, es sei denn, Sie verwenden die Standardeinstellung /. Alle folgenden Vorkommen, die maskiert werden, werden als Literalzeichen und nicht als Endbegrenzer behandelt.

  • Standardtrennzeichen:

    /start/,/end/{/pattern/d;}
    
  • benutzerdefiniertes Trennzeichen:

    \#start#,\#end#{\#pattern#d;}
    

Siehe die POSIX-Dokumente :

In einer Kontextadresse ist die Konstruktion \ cREc, in der c ein anderes Zeichen als ein Backslash- oder Newline-Zeichen ist, identisch mit / RE / Wenn das mit c bezeichnete Zeichen nach einem Backslash erscheint, wird es als das Literalzeichen betrachtet, das beendet den RE nicht. In der Kontextadresse \ xabc \ xdefx steht beispielsweise das zweite x für sich selbst, sodass der reguläre Ausdruck abcxdef lautet.

Ähnliche Beschreibung auf der GNU- sed manSeite:

/regexp/
       Match lines matching the regular expression regexp.      
\cregexpc
       Match lines matching the regular expression regexp.  
       The c may be any character.

und FreeBSD sed manSeite:

In a context address, any character other than a backslash (``\'')
or newline character may be used to delimit the regular expression.
The opening delimiter   needs to be preceded by a backslash unless it
is a slash.  For example, the   context address \xabcx is equivalent
to /abc/.  Also, putting a backslash character before   the delimiting
character within the regular expression causes the character to be
treated literally.  For example, in the context address \xabc\xdefx,
the RE delimiter is an ``x'' and the second ``x'' stands for itself,
so that the regular expression is ``abcxdef''.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.