Sed komutunu kullanmadan dize nasıl bulunur ve değiştirilir?


16

Hepimizin bildiği gibi, sedörnek bulmak 'a' için, dize bulmak ve değiştirmek için büyük ölçüde etkilidir ve 'b' için değiştirin: sed 's/a/b/g'.

Bunu yerine başka komut veya kabuk komut dosyası ile yapmak mümkün mü sed?

Bu, sedkomutu olmayan TV için kırpılmış bir linux sistemleri içindir . Bu yüzden bunun yerine diğer komutları veya komut dosyalarını kullanmalıyımsed 's/a/b/g'. –


Aslında, bu sadece düzenli ifade temelli ikame. Böyle bir şey ele yeteneğine Herhangi alet veya dil aynı şeyi mümkün olacak, ama çeşitli sözdizimi ile: $var=~s/a/b/g, gsub(/a/,"b",var), var.gsub(/a/,'b'), var.replace(/a/g,'b'), preg_replace("/a/","b",$var), regsub -all a b $var. Bunun yanı sıra, birçok araç ve dil düz metin dizesi değiştirme de yapabilir. Yani sorunuz bir şekilde geniş.
manatwork

1
Neden? Ne problemi çözmeye çalışıyorsun?
Gilles 'SO- kötü olmayı kes

TV için kırpılmış bir linux sistemlerinde komut yoktur. Bu yüzden sed 's / a / b / g' yerine başka bir komut veya komut dosyası kullanmalıyım.
binghenzq

Yanıtlar:


12

Evet, bunu yapmanın çeşitli yolları var. Sen kullanabilirsiniz awk, perlya da bashsıra bu faaliyetleri yapmak. Genel olarak sed, muhtemelen bu tür görevleri yapmak için en apropos aracıdır.

Örnekler

Diyelim ki bir dosyada bu örnek veriler var data.txt:

foo bar 12,300.50
foo bar 2,300.50
abc xyz 1,22,300.50

awk

$ awk '{gsub("foo", "foofoofoo", $0); print}' data.txt 
foofoofoo bar 12,300.50
foofoofoo bar 2,300.50
abc xyz 1,22,300.50

Perl

$ perl -pe "s/foo/foofoofoo/g" data.txt 
foofoofoo bar 12,300.50
foofoofoo bar 2,300.50
abc xyz 1,22,300.50

Satır içi düzenleme

Yukarıdaki örnekler dosyaları doğrudan değiştirebilir. Perl örneği önemsizdir. Sadece -ianahtarı ekleyin .

$ perl -pie "s/foo/foofoofoo/g" data.txt 

Çünkü awkbiraz daha az doğrudan ama aynı derecede etkili:

$ { rm data.txt && awk '{gsub("foo", "foofoofoo", $0); print}' > data.txt; } < data.txt

Bu yöntem, parantez '{...} `ile bir alt kabuk oluşturur ve burada dosya bu dosyaya yeniden yönlendirilir:

$ { ... } < data.txt

Dosya alt kabuğa yönlendirildikten sonra silinir ve awkSTDIN alt kabuklarına okunan dosyanın içeriğine karşı çalıştırılır. Bu içerik daha sonra awk, yeni sildiğimiz dosya adıyla işlenir ve yeniden adlandırılır ve etkin bir şekilde değiştirilir.


Cevabınız için teşekkürler ve bir sonraki iş günü deneyeceğim.Ancak işe yarayıp yaramadığından emin değilim, çünkü 'sed' gibi kırpılmış bir linux sistemlerinde bazı komutlar olmayabilir, çünkü hala 'find' komutunu kullanmak istiyorum , 'grep' vb.
binghenzq

@binghenzq - Dosyayı satır içinde düzenleyen örnekler ekledim.
slm

-1 Nadiren aşağı indiririm, ancak bu durumda sorunun amacı diğer / eşit derecede karmaşık ve muhtemelen de bağımlı olmaktan ziyade daha basit bir yöntem gibi görünüyordu. Eğer soru tam * nix makine kurulumu için alternatifler hakkında olsaydı, muhtemelen bu aksi takdirde iyi cevabı + 1'leyecektim.
Michael Durrant

@MichaelDurrant - OP'nin istediği bu ayrıntılı satır içi düzenlemeleri yeni ekledim. Ayrıca OP, I değil DEĞİL kullanma gereksinimini belirledi sed. Sed, bunun gibi ikameler yapmak için uygun bir araçtır ve açıkçası bu araçların rollerini daha iyi anlamasını istiyor, bu yüzden birine kötü olsa da göstermek, göstermede son derece eğitimlidir. neden. Biliyorum birçok kez ppl sadece neden yapmadan açıklamak "yapmayın" demek, bu yüzden öyleyim. Ama en azından neden DV'ye bir yorum bıraktığınız için teşekkürler.
slm

Elbette, bunun diğer tüm açılardan harika bir cevap olduğunu düşündüm. evet -1 açıklamadan nefret ediyorum.
Michael Durrant

13

Tek harfli ikameler için klasik alternatif tr, hemen hemen her sistemde bulunması gereken komuttur:

$ echo "foobar" | tr a b   
foobbr

trdaha iyi olduğu sedaslında kullanarak beri bunu için sed(şöyle dursun perlveya awktek harf değiştirmeler için) bir sineği öldürmek için balyoz kullanmak gibidir.

grep bunun için tasarlanmamıştır, girdisini değiştirmez, sadece içinden arama yapar.

Alternatif olarak, bazı kabukların değiştirme yeteneklerini kullanabilirsiniz . İşte kullanarak ksh, zshya da bashsözdizimi:

$ foo="foobar"
$ echo "${foo//a/b}"
foobbr

Hangi sorunu çözmeye çalıştığınızı tam olarak açıkladıysanız size daha spesifik cevaplar verebiliriz.


Davayı görmezden gelme seçeneği var mı ${foo//a/b}?
AlikElzin-kilaka

@ AlikElzin-kilaka Korkmuyorum. Örneğin gibi daha sofistike bir şey, kullanmak gerekecektir: echo "$foo" | sed 's/a/b/iya bir karakter sınıfını vermek: echo ${foo//[aA]/b}.
terdon

4

Vim'i Ex modunda kullanabilirsiniz:

ex -s -c '%s/a/b/g|x' file
  1. % tüm satırları seç

  2. s vekil

  3. g küresel değiştirme

  4. x kaydet ve kapat


çok teşekkürler. sadece eklemek için, -c bayrağı düzenleme başladığında (ex bir editör olduğu için) komutu yürütmektir ve -s bayrağı ya geri bildirimi devre dışı bırakan komut dosyası kipidir ya da bazıları slient kipinden hoşlanır. daha fazla bilgi için ref: ex-vi.sourceforge.net/ex.html
Jimmy MG Lim

3

Akış yerine bir dosyayla çalışıyorsanız, standart metin düzenleyiciyi kullanabilirsiniz ed:

printf '%s\n' ',s/a/b/g' w q | ed file.txt

Bu herhangi bir * nix'te mevcut olmalıdır. Virgül , her satırda çalışmayı ',s/a/b/g'söyler (ayrıca kullanabilirsiniz , bu da vim yapmaya alışkınsanız daha tanıdık olacaktır) ve geri kalanı standart bir arama ve değiştirme işlemidir. dosyayı yazmasını (kaydetmesini) söyler, çıkmasını söyler.ed%wq

Sed'in -iseçeneğinin (ve diğer araçlardaki benzer seçeneklerin) aksine , bunun aslında geçici dosyalarla hile yapmak yerine dosyayı yerinde düzenlediğini unutmayın.

Bunun akarsularla çalışmasının mümkün olduğunu düşünmüyorum, ama o zaman gerçekten fazla bir şey bilmiyorum edve aslında bu yeteneğe sahipse şaşırmazdım (unix felsefesi ne olduğu).


2

Ancestor komutunu kullanmak ( -syani sessiz (sessiz) anlamına gelir ve komutlardan önceki virgül tüm satırlarda yürütmek anlamına gelir):

Sadece STDOUT üzerine baskı :

ed -s file <<!
,s/a/b/g
,p
q
!

yerinde değiştirme:

ed -s file <<!
,s/a/b/g
w
q
!
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.