Bagaimana saya menggunakan sed untuk menghapus semua baris dalam file teks yang berisi string tertentu?
shell
sed
text-parsing
in-place
A Clockwork Orange
sumber
sumber
sed '/pattern to match/d' ./infile > ./newfile
atau jika Anda ingin melakukan in-place edit maka Anda dapat menambahkan-i
flag ke sed seperti padased -i '/pattern to match/d' ./infile
. Perhatikan bahwa-i
bendera memerlukan sed GNU dan tidak portabelsed -i.backup '/pattern to match/d' ./infile
) Itu membuat saya menyeberang dengan suntingan di tempat.sed
pada file apa pun yang tidak dikontrol versi.sed -i '' '/pattern/d' ./infile
.Ada banyak cara lain untuk menghapus baris dengan string spesifik selain
sed
:AWK
Ruby (1.9+)
Perl
Shell (kurang lebih 3,2 dan lebih baru)
GNU grep
Dan tentu saja
sed
(mencetak kebalikannya lebih cepat daripada penghapusan sebenarnya):sumber
sed
misalnya memiliki perilaku yang berbeda, hanya greps! harus seperti itused -n -i '/pattern/!p' file
.grep -v "pattern" file > temp; mv temp file
Ini mungkin berlaku untuk beberapa contoh lain tergantung pada nilai kembali.seq -f %f 10000000 >foo.txt
. sed d:time sed -i '' '/6543210/d' foo.txt
0m9.294s asli. sed! p:time sed -i '' -n '/6543210/!p' foo.txt
0m13.671s asli. (Untuk file yang lebih kecil, perbedaannya lebih besar.)Anda dapat menggunakan sed untuk mengganti baris yang ada di file. Namun, tampaknya jauh lebih lambat daripada menggunakan grep untuk kebalikannya menjadi file kedua dan kemudian memindahkan file kedua di atas yang asli.
misalnya
atau
Perintah pertama memakan waktu 3 kali lebih lama pada mesin saya.
sumber
sed '/pattern/d' filename > filename2; mv filename2 filename
Cara mudah untuk melakukannya, dengan GNU
sed
:sumber
-r
opsi (atau-E
, tergantung versi Anda). Hal ini memungkinkan penggunaan metakarakter regex+
,?
,{...}
dan(...)
.Anda dapat mempertimbangkan untuk menggunakan
ex
(yang merupakan editor berbasis perintah Unix standar):dimana:
+
mengeksekusi diberi perintah Ex (man ex
), sama seperti-c
yang mengeksekusiwq
(menulis dan berhenti)g/match/d
- Perintah Ex untuk menghapus baris dengan yang diberikanmatch
, lihat: Kekuatan gContoh di atas adalah metode yang sesuai dengan POSIX untuk mengedit file di tempat sesuai pos ini di Unix.SE dan spesifikasi POSIX untuk
ex
.Perbedaannya
sed
adalah:Kecuali Anda menikmati kode yang tidak dapat ditonton, overhead I / O dan beberapa efek samping buruk lainnya. Jadi pada dasarnya beberapa parameter (seperti in-place /
-i
) adalah ekstensi FreeBSD non-standar dan mungkin tidak tersedia pada sistem operasi lain.sumber
man ex
memberi saya laki-laki untukvim
, tampaknyaex
adalah bagian dari vim ... jika saya mengerti benar itu berarti sintaks pola untukmatch
adalah vimregex.com yang mirip tetapi berbeda dengan rasa POSIX dan PCRE?:g
adalah perintah yang sesuai dengan POSIX dengan beberapa perbedaan kecil . Saya menganggap PCRE didasarkan pada itu.Saya berjuang dengan ini di Mac. Plus, saya harus melakukannya menggunakan penggantian variabel.
Jadi saya menggunakan:
sed -i '' "/$pattern/d" $file
dimana
$file
file dimana penghapusan dibutuhkan dan$pattern
merupakan pola yang cocok untuk dihapus.Saya memilih
''
dari komentar ini .Hal yang perlu diperhatikan di sini adalah penggunaan tanda kutip ganda di
"/$pattern/d"
. Variabel tidak akan berfungsi ketika kami menggunakan tanda kutip tunggal.sumber
sed
memerlukan parameter setelahnya-i
, jadi jika Anda tidak ingin cadangan, Anda masih harus menambahkan string kosong:-i ''
sed -i "/$pattern/d" $file
. Terima kasih atas jawaban Anda.Saya telah membuat patokan kecil dengan file yang berisi sekitar 345.000 baris. Cara dengan
grep
tampaknya sekitar 15 kali lebih cepat daripadased
metode dalam kasus ini.Saya telah mencoba keduanya dengan dan tanpa pengaturan LC_ALL = C, sepertinya tidak mengubah timing secara signifikan. String pencarian (CDGA_00004.pdbqt.gz.tar) ada di suatu tempat di tengah file.
Berikut adalah perintah dan timingnya:
sumber
Anda juga dapat menggunakan ini:
Di sini
-v
hanya akan mencetak selain pola Anda (itu berarti kecocokan terbalik).sumber
Untuk mendapatkan inplace seperti hasil dengan
grep
Anda dapat melakukan ini:sumber
bash
shell atau sejenisnya (tidaktcsh
).SED:
'/James\|John/d'
-n '/James\|John/!p'
AWK:
'!/James|John/'
/James|John/ {next;} {print}
GREP:
-v 'James\|John'
sumber
Perintah pertama mengedit file di tempat (-i).
Perintah kedua melakukan hal yang sama tetapi menyimpan salinan atau cadangan file asli dengan menambahkan .bk ke nama file (.bk dapat diubah menjadi apa saja).
sumber
echo -e "/thing_to_delete\ndd\033:x\n" | vim file_to_edit.txt
sumber
Untuk berjaga - jaga seandainya seseorang ingin melakukannya untuk kecocokan string yang tepat, Anda dapat menggunakan
-w
flag dalam grep - w secara keseluruhan. Misalnya, jika Anda ingin menghapus garis yang memiliki angka 11, tetapi pertahankan garis dengan angka 111:Ini juga berfungsi dengan
-f
bendera jika Anda ingin mengecualikan beberapa pola yang tepat sekaligus. Jika "daftar hitam" adalah file dengan beberapa pola pada setiap baris yang ingin Anda hapus dari "file":sumber
-w, --word-regexp Select only those lines containing matches that form whole words.
vs.-x, --line-regexp Select only those matches that exactly match the whole line. For a regular expression pattern, this is like parenthesizing the pattern and then surrounding it with ^ and $.
sumber
untuk menampilkan teks yang dirawat di konsol
untuk menyimpan teks yang dirawat ke dalam file
untuk menambahkan info teks yang diperlakukan file yang ada
untuk memperlakukan teks yang sudah diperlakukan, dalam hal ini hapus lebih banyak baris dari apa yang telah dihapus
yang
| more
akan menampilkan teks dalam potongan satu halaman pada satu waktu.sumber
Anda bisa menggunakan yang lama
ed
untuk mengedit file dengan cara yang mirip dengan jawaban yang digunakanex
. Perbedaan besar dalam hal ini adalah bahwaed
mengambil perintah melalui input standar, bukan sebagai argumen baris perintah sepertiex
bisa. Saat menggunakannya dalam skrip, cara biasa untuk mengakomodasi ini adalah dengan menggunakanprintf
perintah pipa ke sana:atau dengan heredoc:
sumber