Wie lösche ich den Rest jeder Zeile nach einem bestimmten Muster oder einer Zeichenfolge in einer Datei?

21

Angenommen, ich habe eine Liste von URLs in einer Textdatei:

google.com/funny
unix.stackexchange.com/questions
isuckatunix.com/ireallydo

Ich möchte alles löschen, was nach ".com" kommt.

Erwartete Ergebnisse:

google.com
unix.stackexchange.com
isuckatunix.com

Ich habe es versucht

sed 's/.com*//' file.txt 

aber es wurde auch gelöscht .com.

Koshur
quelle
Gibt es einen bestimmten Grund, nach dem Sie .comnur suchen möchten, anstatt alles nach und einschließlich des ersten /Zeichens zu entfernen ? Was wäre, wenn Sie eine URL wie en.wikipedia.org/wiki/Ubuntuin Ihrer Liste hätten?
Byte Commander

Antworten:

17

Um explizit alles zu löschen, was nach ".com" kommt, müssen Sie nur Ihre vorhandene sed-Lösung optimieren, um ".com (irgendetwas)" durch ".com" zu ersetzen:

sed 's/\.com.*/.com/' file.txt

Ich habe deine Regex angepasst, um der ersten Periode zu entkommen. Andernfalls hätte es zu "thisiscommon.com/something" gepasst.

Beachten Sie, dass Sie das ".com" -Muster möglicherweise mit einem abschließenden Schrägstrich weiter verankern möchten, damit Sie nicht versehentlich etwas wie "sub.com.domain.com/foo" abschneiden:

sed 's/\.com\/.*/.com/' file.txt
Jeff Schaller
quelle
9

Sie können das awkFeldtrennzeichen ( -F) folgendermaßen verwenden:

$ cat file
google.com/funny
unix.stackexchange.com/questions
isuckatunix.com/ireallydo

$ cat file | awk -F '\\.com' '{print $1".com"}'
google.com
unix.stackexchange.com
isuckatunix.com

Erläuterung:

NAME
       awk - pattern scanning and processing language

-F fs
       --field-separator fs
              Use fs for the input field separator (the value of the FS predefined variable).

Wenn Sie alle nachfolgenden Elemente löschen möchten .com, -F '.com'trennen Sie die Zeile mit .comund print $1geben Sie nur den vorherigen Teil aus .com. Fügt also $1".com"hinzu .comund liefert die erwartete Ausgabe.

Pandya
quelle
Warum nicht einfach /als FS und das erste Feld nehmen?
Heemayl
1
@ Pandya: Dies scheitert mit Zeichenfolge wieacomercial.com/asdsad
Cuonglm
@ Cuonglm Danke für den Hinweis. Verbesserte Antwort
Pandya
4

Das beste Tool für die nicht interaktive direkte Bearbeitung von Dateien ist ex.

ex -sc '%s/\(\.com\).*/\1/ | x' file.txt

Wenn Sie vieinen Befehl verwendet haben und dieser mit einem Doppelpunkt beginnt, haben :Sie einen ex-Befehl verwendet. Natürlich sind viele der fortgeschrittenen oder "ausgefallenen" Befehle, die Sie auf diese Weise ausführen können, Vim-Erweiterungen (z. B. :bufdo) und sind nicht in den POSIX-Spezifikationen für definiertex , aber diese Spezifikationen ermöglichen ein wirklich erstaunliches Maß an Leistung und Flexibilität in nicht visuellen Bereichen Textbearbeitung (interaktiv oder automatisiert).

Der obige Befehl besteht aus mehreren Teilen.

-sAktiviert den unbeaufsichtigten Modus, um die exStapelverwendung vorzubereiten . (Unterdrückung von Ausgabenachrichten ua)

-cGibt den Befehl an, der ausgeführt werden soll, sobald die Datei ( file.txtin diesem Fall) in einem Puffer geöffnet wurde.

%ist ein Adressenspezifizierer, der 1,$- es bedeutet, dass der folgende Befehl auf alle Zeilen des Puffers angewendet wird.

sist der Ersatzbefehl, mit dem Sie wahrscheinlich bereits vertraut sind. Es wird häufig in viund mit im Wesentlichen identischen Funktionen wie der sBefehl von verwendetsed , obwohl einige der erweiterten regulären Funktionen je nach Implementierung variieren können. In diesem Fall wird von ".com" bis zum Ende der Zeile nur ".com" verwendet.

Die vertikale Leiste trennt die auszuführenden sequentiellen Befehle. In vielen (den meisten) exImplementierungen können Sie auch eine zusätzliche -cOption verwenden, z.

ex -sc '%s/\(\.com\).*/\1/' -c x file.txt

Dies wird jedoch von POSIX nicht benötigt.

Der xBefehl wird beendet, nachdem Änderungen an der Datei geschrieben wurden. Im Gegensatz zu wq"Schreiben und Beenden" wird xin die Datei nur geschrieben, wenn der Puffer bearbeitet wurde. Wenn also Ihre Datei unverändert bleibt, bleibt der Zeitstempel erhalten.

Platzhalter
quelle
1
1 für die Verwendung von ex
Jeff Schaller
1
Es wird nicht direkt bearbeitet. Zumindest tut es nicht mehr als Gnus Schwindel sed-i. Es liest / schreibt in die Festplattenpuffer. Überzeugen Sie sich selbst mit ex -rdem preserveBefehl.
mikeserv
@mikeserv Was ist der preserveBefehl?
Mateen Ulhaq
2

Sehr schnelle, einfache und schmutzige Python-Methode:

#!/usr/bin/env python
import sys
with open( sys.argv[1]  ) as file:
    for line in file:
        print line.split("/")[0]

Probelauf

skolodya@ubuntu:$ chmod +x removeStrings.py                                   

skolodya@ubuntu:$ ./removeStrings.py strings.txt                              
google.com
unix.stackexchange.com
isuckatunix.com


skolodya@ubuntu:$ cat strings.txt                                             
google.com/funny
unix.stackexchange.com/questions
isuckatunix.com/ireallydo
Sergiy Kolodyazhnyy
quelle
2
Kann ich bitte den Grund für die Ablehnung wissen?
Sergiy Kolodyazhnyy
3
Es funktioniert, kümmert sich aber nicht darum .com, sondern entfernt einfach alles, beginnend mit dem ersten /in der Zeile. (Das ist meiner Meinung nach sogar der bessere Ansatz!)
Byte Commander
1
@ByteCommander genau richtig! Wenn der Domänenname lautet .net, wird in anderen Ansätzen der Teil nach der Domäne und der Erweiterung nicht gelöscht. Daher ist es sicherer, ihn /als Trennzeichen zu verwenden.
Sergiy Kolodyazhnyy
+1 für Antworten und Kommentare, bei denen ich mich wie in AskUbuntu.com fühle: D
WinEunuuchs2Unix