Bagaimana cara menghapus sisa setiap baris setelah pola atau string tertentu dalam file?

21

Misalkan saya memiliki daftar URL dalam file teks:

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

Saya ingin menghapus semua yang muncul setelah '.com'.

Hasil yang diharapkan:

google.com
unix.stackexchange.com
isuckatunix.com

Saya mencoba

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

tapi itu dihapus .comjuga.

Koshur
sumber
Apakah ada alasan khusus yang ingin Anda cari .comhanya alih-alih menghapus semuanya setelah dan termasuk /karakter pertama ? Bagaimana jika Anda memiliki URL seperti en.wikipedia.org/wiki/Ubuntudi daftar Anda?
Byte Commander

Jawaban:

17

Untuk secara eksplisit menghapus semua yang muncul setelah ".com", cukup atur solusi sed yang ada untuk mengganti ".com (apa saja)" dengan ".com":

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

Saya men-tweak regex Anda untuk menghindari periode pertama; kalau tidak, itu akan cocok dengan sesuatu seperti "thisiscommon.com/something".

Perhatikan bahwa Anda mungkin ingin lebih jauh mengaitkan pola ".com" dengan garis miring ke belakang sehingga Anda tidak sengaja memotong sesuatu seperti "sub.com.domain.com/foo":

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

Anda dapat menggunakan awkpemisah bidang ( -F) dengan cara berikut:

$ 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

Penjelasan:

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

Karena Anda ingin menghapus semua hal setelahnya .com, -F '.com'pisahkan baris dengan .comdan print $1hanya berikan keluaran bagian sebelumnya .com. Jadi, $1".com"tambahkan .comdan beri Anda hasil yang diharapkan.

Pandya
sumber
Mengapa tidak /seperti FS dan ambil bidang pertama?
heemayl
1
@ Pandya: Ini gagal dengan string sepertiacomercial.com/asdsad
cuonglm
@cuonglm Terima kasih telah menunjukkan. Jawaban yang ditingkatkan
Pandya
4

Alat terbaik untuk mengedit file di tempat non-interaktif adalah ex.

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

Jika Anda telah menggunakan vidan jika Anda pernah mengetik perintah yang dimulai dengan titik dua :Anda telah menggunakan perintah ex. Tentu saja banyak dari perintah yang lebih maju atau "mewah" yang dapat Anda lakukan dengan cara ini adalah ekstensi Vim (mis. :bufdo) Dan tidak ditentukan dalam spesifikasi POSIX untukex , tetapi spesifikasi tersebut memungkinkan untuk tingkat daya dan fleksibilitas yang benar-benar menakjubkan di non-visual. pengeditan teks (apakah interaktif atau otomatis).

Perintah di atas memiliki beberapa bagian.

-smemungkinkan mode hening untuk mempersiapkan expenggunaan bets. (Menekan pesan output dkk.)

-cmenentukan perintah untuk mengeksekusi setelah file ( file.txt, dalam kasus ini) dibuka di buffer.

%adalah specifier alamat yang setara dengan 1,$— itu berarti bahwa perintah berikut diterapkan ke semua baris buffer.

sadalah perintah pengganti yang mungkin sudah Anda kenal. Ini biasa digunakan divi dan pada dasarnya memiliki fitur yang identik dengan sperintahsed , meskipun beberapa fitur regex canggih dapat bervariasi berdasarkan implementasi. Dalam hal ini dari ".com" hingga akhir baris diganti dengan hanya ".com".

Bilah vertikal memisahkan perintah berurutan yang akan dieksekusi. Dalam banyak (sebagian besar)ex implementasi, Anda juga dapat menggunakan -copsi tambahan , seperti:

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

Namun, ini tidak diperlukan oleh POSIX.

The xperintah keluar, setelah menulis perubahan ke file. Berbeda dengan wqyang berarti "menulis dan berhenti", xhanya menulis ke file jika buffer telah diedit. Jadi, jika file Anda tidak diubah, stempel waktu akan dipertahankan.

Wildcard
sumber
1
+1 untuk menggunakan mantan
Jeff Schaller
1
Itu tidak mengedit di tempat. Setidaknya, itu tidak lebih dari sedpalsu Gnu - saya lakukan. Itu membaca / menulis ke buffer pada disk. Lihat sendiri w / ex -rdan preserveperintahnya.
mikeserv
@ mikeserv Apa preserveperintahnya?
Mateen Ulhaq
2

Cara python yang sangat cepat, sederhana dan kotor:

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

Contoh dijalankan

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
sumber
2
Bolehkah saya tahu alasan downvote?
Sergiy Kolodyazhnyy
3
Berhasil, tetapi tidak peduli .com, hanya menghapus semuanya dimulai dengan yang pertama /di baris. (yang menurut saya bahkan pendekatan yang lebih baik!)
Byte Commander
1
@ByteCommander tepat sekali! Jika nama domain adalah .net, dalam pendekatan lain bagian yang datang setelah domain dan ekstensi tidak akan dihapus, jadi lebih aman untuk digunakan /sebagai pemisah.
Sergiy Kolodyazhnyy
+1 untuk jawaban dan komentar yang membuat saya merasa seperti berada di AskUbuntu.com: D
WinEunuuchs2Unix