it-swarm.com.de

Wie kann ich alles bis zu einem Muster und alles nach einem anderen Muster aus einer Zeile löschen?

In der folgenden Datei:

Lorem ipsum dolor sitzen amet, consectetuer adipiscing elit. Ut eu metus id lectus vestibulum ultrices. Maecenas rhoncus.

Ich möchte alles vor consectetuer und alles nach elit löschen.

Meine gewünschte Ausgabe:

consectetuer adipiscing elit.

Wie kann ich das machen?

17
manuel

Ich würde sed verwenden

sed 's/^.*\(consectetuer.*elit\).*$/\1/' file

Dekodierte die sed s/find/replace/syntax:

  • s/^.* - Ersetzen Sie am Zeilenanfang (^), Gefolgt von allem (.*) Bis zu ...
  • \( - Starten Sie einen benannten Block
  • consectetuer.*elit\. - Ordnen Sie das erste Wort, alles (.*) Bis zum letzten Wort (in diesem Fall einschließlich des nachgestellten (maskierten) Punkts) zu, mit dem Sie übereinstimmen möchten
  • \) - Beende den benannten Block
  • ordne alles andere (.*) dem Ende der Zeile zu ($).
  • / - Beenden Sie den Ersatzsuchabschnitt
  • \1 - durch den Namensblock zwischen \( Und \) Oben ersetzen
  • / - Beenden Sie den Austausch
28
MikeV

Wenn jede Zeile sowohl Start- als auch Endmuster enthält, ist dies am einfachsten mit grep. Anstatt den Anfang und das Ende jeder Zeile zu löschen , können Sie einfach den Inhalt zwischen beiden Mustern ausgeben. Das -o Option in GNU grep gibt nur die Übereinstimmungen aus:

grep -o 'consectetuer.*elit' file

Hinweis: Wie bereits erwähnt, funktioniert dies nur, wenn jede Zeile in der Datei auf diese Weise analysiert werden kann. Andererseits sind das 80% aller typischen Anwendungsfälle.

7
slebetman

Zwei for-Schleifen in AWK:

$ awk '{for(i=1;i<=NF;i++) {if ($i == "consectetuer") beginning=i; if($i== "elit.") ending=i }; for (j=beginning;j<=ending;j++) printf $j" ";printf "\n"   }' file.txt 
consectetuer adipiscing elit.

AWKs gsub:

$ awk '{gsub(/^.*consectetuer/,"consectetuer"); gsub(/elit.*$/,"elit.");print}' file.txt
consectetuer adipiscing elit.
1

Ein Perl-Weg. Dies ist im Wesentlichen dasselbe wie MikeVs sed Antwort:

Perl -pe 's/.*(consectetuer.*elit).*./$1/' file

Das -p Bedeutet "jede Zeile drucken, nachdem das mit -e Angegebene Skript angewendet wurde". Der s/foo/bar/ Ist der Substitutionsoperator. es wird foo durch bar ersetzen. Die Klammern erfassen ein Muster und lassen uns es beim Ersetzen verwenden. Das erste erfasste Muster ist $1, Das zweite $2 Und so weiter.

Der Befehl stimmt also alles bis zu consectetuer (.*consectetuer) Ab, dann alles bis elit (.*elit) Und dann alles andere bis zum Ende des Zeile (.*) und ersetzt diese durch das erfasste Muster.

1
terdon

Ich bin nicht sicher, warum dieser Fragentitel " von Datei" zu " von einer Zeile" bearbeitet wurde, während das OP die Möglichkeit nicht ausschließt mehrere Zeilen, obwohl das Beispiel nur eine Zeile zu sein scheint. Wie auch immer, es kann hilfreich sein, hier eine Lösung mit mehreren Leitungen bereitzustellen.

Dies funktioniert für Crosslines:

from1=consectetuer; to2=elit; a="$(cat file)"; a="$(echo "${a#*"$from1"}")"; echo "$from1${a%%"$to2"*}$to2"

Beispiele:

[[email protected] tmp]$ cat file
1
abc consectetuer lsl

home

def elit dd
2 consectetuer ABC elit
[[email protected] tmp]$ from1=consectetuer; to2=elit; a="$(cat file)"; a="$(echo "${a#*"$from1"}")"; echo "$from1${a%%"$to2"*}$to2"
consectetuer lsl

home

def elit
[[email protected] tmp]$ 

referenz: Shell Parameter Expansion

1
林果皞