Come eliminare il resto di ogni riga dopo un certo modello o una stringa in un file?


21

Supponiamo di avere un elenco di URL in un file di testo:

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

Voglio eliminare tutto ciò che viene dopo '.com'.

Risultati aspettati:

google.com
unix.stackexchange.com
isuckatunix.com

Provai

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

ma anche cancellato .com.


C'è un motivo specifico per cui vuoi cercare .comsolo invece di rimuovere tutto dopo e incluso il primo /carattere? E se avessi un URL come en.wikipedia.org/wiki/Ubuntunella tua lista?
Byte Commander,

Risposte:


17

Per eliminare esplicitamente tutto ciò che viene dopo ".com", basta modificare la soluzione sed esistente per sostituire ".com (qualunque)" con ".com":

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

Ho ottimizzato la tua regex per sfuggire al primo periodo; altrimenti avrebbe abbinato qualcosa come "thisiscommon.com/something".

Tieni presente che potresti voler ancorare ulteriormente il modello ".com" con una barra rovesciata in modo da non tagliare accidentalmente qualcosa come "sub.com.domain.com/foo":

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

9

È possibile utilizzare awkil separatore di campo ( -F) nel modo seguente:

$ 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

Spiegazione:

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).

Come vuoi eliminare ogni cosa dopo .com, -F '.com'separa la linea con .come print $1dà in output solo la parte prima .com. Quindi, $1".com"aggiunge .come ti dà l'output previsto.


Perché non solo /come FS e prendere il primo campo?
Hememl


1
@Pandya: questo fallisce con una stringa comeacomercial.com/asdsad
cuonglm,

@cuonglm Grazie per averci segnalato. Risposta migliorata
Pandya,

4

Lo strumento migliore per la modifica dei file sul posto non interattivo è ex.

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

Se hai usato vie se hai mai digitato un comando che inizia con due punti :hai usato un comando ex. Naturalmente molti dei comandi più avanzati o "fantasiosi" che puoi eseguire in questo modo sono estensioni di Vim (ad es. :bufdo) E non sono definiti nelle specifiche POSIX perex , ma tali specifiche consentono un grado davvero sorprendente di potenza e flessibilità in modalità non visiva modifica del testo (interattivo o automatico).

Il comando sopra ha più parti.

-sabilita la modalità silenziosa per prepararsi exall'uso in batch. (Sopprime i messaggi di output et al.)

-cspecifica il comando da eseguire dopo l' file.txtapertura del file ( , in questo caso) in un buffer.

%è un identificatore di indirizzo equivalente a 1,$—it significa che il seguente comando viene applicato a tutte le righe del buffer.

sè il comando sostitutivo che probabilmente conosci già. È comunemente usato vie ha essenzialmente identiche funzionalità al scomando dised , sebbene alcune delle funzionalità regex avanzate possano variare in base all'implementazione. In questo caso da ".com" alla fine della riga viene sostituito solo con ".com".

La barra verticale separa i comandi sequenziali da eseguire. In molte (la maggior parte) eximplementazioni puoi anche usare -cun'opzione aggiuntiva , in questo modo:

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

Tuttavia, ciò non è richiesto da POSIX.

Il xcomando termina, dopo aver scritto tutte le modifiche al file. Diversamente dal wqsignificato di "scrittura ed uscita", xscrive sul file solo se il buffer è stato modificato. Pertanto, se il file non viene modificato, il timestamp verrà conservato.


1
+1 per l'utilizzo dell'ex
Jeff Schaller

1
Non modifica sul posto. Almeno, non lo è più del sedfalso- di Gnu . Legge / scrive su buffer su disco. Guarda tu stesso con ex -ril preservecomando.
Mikeserv,

@mikeserv Qual è il preservecomando?
Mateen Ulhaq,

2

Modo pitone molto veloce, semplice e sporco:

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

Esecuzione del campione

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

2
Potrei per favore sapere il motivo del downvote?
Sergiy Kolodyazhnyy,

3
Funziona, ma non gliene importa .com, rimuove semplicemente tutto a partire dal primo /della riga. (che secondo me è anche l'approccio migliore!)
Byte Commander,

1
@ByteCommander esattamente! Se il nome di dominio è .net, in altri approcci la parte che segue il dominio e l'estensione non verrebbe eliminata, quindi è più sicuro usare /come separatore.
Sergiy Kolodyazhnyy,

+1 per la risposta e i commenti che mi fanno sentire come se fossi in AskUbuntu.com: D
WinEunuuchs2Unix
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.