Pertanyaan Cari dan ganti teks dalam file menggunakan perintah


Bagaimana saya bisa menemukan dan mengganti kata-kata tertentu dalam file teks menggunakan baris perintah?


434
2018-01-07 04:10


asal


Semoga minat Anda github.com/lucio-martinez/rch :-) - Lucio


Jawaban:


sed -i 's/original/new/g' file.txt

Penjelasan:

  • sed = Streaming EDitor
  • -i = in-place (misal, simpan kembali ke file asli)
  • String perintah:

    • s = perintah pengganti
    • original = ekspresi reguler yang menggambarkan kata untuk menggantikan (atau hanya kata itu sendiri)
    • new = teks untuk menggantinya dengan
    • g = global (yaitu mengganti semua dan bukan hanya kejadian pertama)
  • file.txt = nama file


724
2018-01-07 04:23



@mcExchange Jika secara khusus / karakter yang perlu Anda cocokkan, Anda bisa menggunakan beberapa karakter lain sebagai pemisah (mis. 's_old/text_new/text_g'). Jika tidak, Anda dapat meletakkan \  sebelum ada $ * . [ \ ^ untuk mendapatkan karakter literal. - cscarney
@ BrianZ Sejauh sistem file yang bersangkutan output dari sed adalah file baru dengan nama yang sama. Itu salah satunya biasanya melaporkan bug yang bukan bug - cscarney
Anda mungkin menginginkannya s/\boriginal\b/new/g dari pada s/original/new/g (\b cocok dengan batas kata) untuk hanya mengganti seluruh kata. - Chris Martin
Perintah OSX sed -i '.bak' 's/original/new/g' file.txt juga bisa dijalankan dengan ekstensi nol-panjang sed -i '' 's/original/new/g' file.txt, yang tidak akan menghasilkan cadangan. - Kirk
Pengguna MacOS harus menambahkan '' "setelah -i sebagai parameter untuk -i ed.gs/2016/01/26/os-x-sed-invalid-command-code sehingga file akan ditimpa. - geoyws


Ada sejumlah cara berbeda untuk melakukan ini. Yang satu menggunakan sed dan Regex. SED adalah Editor Stream untuk memfilter dan mengubah teks. Salah satu contohnya adalah sebagai berikut:

marco@imacs-suck: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orly
marco@imacs-suck: ~$ sed s/slow/quick/ < orly > yarly
marco@imacs-suck: ~$ cat yarly
The quick brown unicorn jumped over the hyper sleeping dog

Cara lain yang mungkin lebih masuk akal daripada < strin dan > strout adalah dengan pipa!

marco@imacs-suck: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowai
marco@imacs-suck: ~$ cat nowai 
The quick brown fox jumped over the lazy sleeping dog

26
2018-01-07 04:26



perhatikan cat di cat file | sed '...' tidak perlu. Anda bisa langsung mengatakannya sed '...' file. - fedorqui
Memang ini dapat dikurangi lebih jauh: sed -i'.bak' -e 's/unicorn/fox/g;s/hyper/brown/g' yarly akan mengambil file yarly dan melakukan 2 perubahan di tempat sementara membuat cadangan. Menggunakan time bash -c "$COMMAND" ke waktu itu menunjukkan bahwa versi ini ~ 5 kali lebih cepat. - pbhj


Anda dapat menggunakan Vim dalam mode Ex:

ex -sc '%s/OLD/NEW/g|x' file
  1. % pilih semua garis

  2. s pengganti

  3. g ganti semua instance di setiap baris

  4. x tulis jika perubahan telah dilakukan (mereka) dan keluar


15
2018-04-16 18:36





Melalui perintah gsub awk,

awk '{gsub(/pattern/,"replacement")}' file

Contoh:

awk '{gsub(/1/,"0");}' file

Dalam contoh di atas, semua 1 diganti dengan 0 terlepas dari kolom di mana ia berada.


Jika Anda ingin melakukan penggantian pada kolom tertentu maka lakukan seperti ini,

awk '{gsub(/pattern/,"replacement",column_number)}' file

Contoh:

awk '{gsub(/1/,"0",$1);}' file

Ini menggantikan 1 dengan 0 pada kolom 1 saja.

Melalui Perl,

$ echo 'foo' | perl -pe 's/foo/bar/g'
bar

14
2017-07-02 12:59



Saya menggunakan ini di terminal MacOS dan tidak melakukan apa pun ... - Jim


Ada banyak cara untuk mencapainya. Tergantung pada kerumitan apa yang coba dicapai dengan penggantian string, dan tergantung pada alat yang akrab dengan pengguna, beberapa metode mungkin lebih disukai daripada yang lain.

Dalam jawaban ini saya menggunakan sederhana input.txt file, yang dapat Anda gunakan untuk menguji semua contoh yang disediakan di sini. Isi file:

roses are red , violets are blue
This is an input.txt and this doesn't rhyme

PESTA

Bash tidak benar-benar dimaksudkan untuk pemrosesan teks, tetapi substitusi sederhana dapat dilakukan melalui ekspansi parameter , khususnya di sini kita dapat menggunakan struktur sederhana ${parameter/old_string/new_string}.

#!/bin/bash
while IFS= read -r line
do
    case "$line" in
       *blue*) printf "%s\n" "${line/blue/azure}" ;;
       *) printf "%s\n" "$line" ;;
    esac
done < input.txt

Skrip kecil ini tidak melakukan penggantian di tempat, yang berarti Anda harus menyimpan teks baru ke file baru, dan menyingkirkan file lama, atau mv new.txt old.txt

Catatan sampingan: jika Anda ingin tahu tentang alasannya while IFS= read -r ; do ... done < input.txt digunakan, itu pada dasarnya cara shell membaca file baris demi baris. Lihat ini sebagai referensi.

AWK

AWK, menjadi utilitas pemrosesan teks, cukup tepat untuk tugas semacam itu. Dapat melakukan penggantian sederhana dan jauh lebih maju berdasarkan ekspresi reguler. Ini menyediakan dua fungsi: sub() dan gsub(). Yang pertama hanya menggantikan hanya kejadian pertama, sedangkan yang kedua - menggantikan kejadian dalam string keseluruhan. Misalnya, jika kita memiliki string one potato two potato , ini akan menjadi hasilnya:

$ echo "one potato two potato" | awk '{gsub(/potato/,"banana")}1'
one banana two banana

$ echo "one potato two potato" | awk '{sub(/potato/,"banana")}1'                                      
one banana two potato 

AWK dapat mengambil file input sebagai argumen, jadi lakukan hal yang sama dengan input.txt , akan mudah:

awk '{sub(/blue/,"azure")}1' input.txt

Tergantung pada versi AWK yang Anda miliki, mungkin atau mungkin tidak memiliki pengeditan di tempat, maka praktik yang biasa adalah menyimpan dan mengganti teks baru. Misalnya sesuatu seperti ini:

awk '{sub(/blue/,"azure")}1' input.txt > temp.txt && mv temp.txt input.txt

SED

Sed adalah seorang editor garis. Ia juga menggunakan ekspresi reguler, tetapi untuk substitusi sederhana, ini cukup untuk dilakukan:

sed 's/blue/azure/' input.txt

Apa yang baik tentang alat ini adalah memiliki pengeditan di tempat, yang dapat Anda aktifkan -i bendera.

Perl

Perl adalah alat lain yang sering digunakan untuk pemrosesan teks, tetapi itu adalah bahasa tujuan umum, dan digunakan dalam jaringan, administrasi sistem, aplikasi desktop, dan banyak tempat lainnya. Ia meminjam banyak konsep / fitur dari bahasa lain seperti C, sed, awk, dan lain-lain. Substitusi sederhana dapat dilakukan seperti ini:

perl -pe 's/blue/azure/' input.txt

Seperti sed, perl juga memiliki bendera -i.

Python

Bahasa ini sangat serbaguna dan juga digunakan dalam berbagai macam aplikasi. Ini memiliki banyak fungsi untuk bekerja dengan string, di antaranya replace(), jadi jika Anda memiliki variabel seperti var="Hello World" , Anda bisa melakukannya var.replace("Hello","Good Morning")

Cara sederhana untuk membaca file dan mengganti string di dalamnya akan menjadi seperti ini:

python -c "import sys;lines=sys.stdin.read();print lines.replace('blue','azure')" < input.txt

Dengan Python, Anda juga perlu melakukan output ke file baru, yang juga dapat Anda lakukan dari dalam skrip itu sendiri. Misalnya, inilah yang sederhana:

#!/usr/bin/env python
import sys
import os
import tempfile

tmp=tempfile.mkstemp()

with open(sys.argv[1]) as fd1, open(tmp[1],'w') as fd2:
    for line in fd1:
        line = line.replace('blue','azure')
        fd2.write(line)

os.rename(tmp[1],sys.argv[1])

Skrip ini harus dipanggil dengan input.txt sebagai argumen baris perintah.

Python juga dapat memiliki ekspresi reguler, khususnya, ada re modul, yang memiliki re.sub() fungsi, yang dapat digunakan untuk penggantian yang lebih canggih.


12
2018-02-03 07:49





sed adalah stream editor, yang bisa Anda gunakan | (pipa) untuk dikirim aliran standar (STDIN dan STDOUT secara khusus) melalui sed dan mengubahnya secara terprogram dengan cepat, membuatnya menjadi alat yang berguna dalam tradisi filsafat Unix; tetapi dapat mengedit file secara langsung, juga menggunakan -i parameter yang disebutkan di bawah ini.
Pertimbangkan yang berikut ini:

sed -i -e 's/few/asd/g' hello.txt

s/ digunakan untuk smengganti ungkapan yang ditemukan few dengan asd:

Yang sedikit, yang pemberani.


The asd, si pemberani.

/g singkatan dari "global", yang berarti melakukan ini untuk seluruh baris. Jika Anda meninggalkan /g (dengan s/few/asd/, selalu harus ada tiga garis miring, tidak peduli apa) dan few muncul dua kali pada baris yang sama, hanya yang pertama few diubah menjadi asd:

Beberapa pria, beberapa wanita, pemberani.


Para pria, beberapa wanita, pemberani.

Ini berguna dalam beberapa keadaan, seperti mengubah karakter khusus di awal baris (misalnya, mengganti simbol yang lebih besar dari yang digunakan sebagian orang untuk mengutip materi sebelumnya di utas email dengan tab horizontal sambil meninggalkan ketidaksetaraan aljabar yang dikutip kemudian di baris tidak tersentuh), tetapi dalam contoh Anda di mana Anda menentukan itu di mana saja  few terjadi itu harus diganti, pastikan Anda memilikinya /g.

Dua opsi berikut (bendera) digabungkan menjadi satu, -ie:

-i opsi digunakan untuk mengedit sayan tempat pada file hello.txt.

-e opsi menunjukkan expression / perintah untuk menjalankan, dalam hal ini s/.

Catatan: Sangat penting yang Anda gunakan -i -e untuk mencari / mengganti. Jika kamu melakukan -ie, Anda membuat cadangan dari setiap file dengan huruf 'e' ditambahkan.


6
2017-11-23 09:00





Anda dapat melakukan seperti ini:

locate <part of filaname to locate> | xargs sed -i -e "s/<Old text>/<new text>/g" 

Contoh: untuk mengganti semua kemunculan [logdir ',' '] (tanpa []) dengan [logdir', os.getcwd ()] di semua file yang merupakan hasil dari perintah locate, lakukan:

locate tensorboard/program.py | xargs sed -i -e "s/logdir', ''/logdir', os.getcwd()/g"

di mana [tensorboard / program.py] adalah file untuk dicari


0
2017-07-24 02:13



Hai. Pilihan string Anda (logdir', '' -> /logdir', os.getcwd()) membuat jawaban ini sulit diuraikan. Juga, perlu ditentukan bahwa jawaban Anda pertama menempatkan file untuk menggunakan sed pada, karena itu bukan bagian dari pertanyaan. - mwfearnley
Hai, jawaban ini baik mencari dan mengganti semua jika menemukan <teks lama> di file. - Nguyễn Tuấn Anh
Saya memilih jawaban ini untuk semua yang mereka gunakan tensorboard dalam keras, yang ingin mengubah perintah dari: tensorboard --logdir = '/ path / ke / log / folder /' untuk digunakan: tensorboard saja, ketika tinggal di folder log. itu sangat nyaman - Nguyễn Tuấn Anh