Awk veya sed ile bir dizenin özyinelemeli bulma / değiştirme nasıl yapılır?


677

Her tekrarını nasıl bulabilir ve değiştirebilirim:

subdomainA.example.com

ile

subdomainB.example.com

/home/www/dizinin altındaki her metin dosyasında özyinelemeli?


93
İpucu: Bir svn ödeme ağacında aşağıdakileri yapmayın ... sihirli .svn klasör dosyalarının üzerine yazılır.
J. Polfer

7
Aman tanrım, tam da bunu yaptım. Ama işe yaradı ve herhangi bir zarar vermedi gibi görünüyor. Bunun olabileceği en kötü şey nedir?
J. Katzwinkel

5
@ J.Katzwinkel: en azından deponuzu bozabilecek sağlama toplamlarını bozabilir.
ninjagecko

3
Sed kullanan herkes için hızlı ipucu: Dosyalarınıza sondaki yeni satırlar ekleyecektir. Onları istemiyorsanız, önce hiçbir şeyle eşleşmeyen bir bul-değiştir işlemi yapın ve bunu gitmeye bırakın. O zaman gerçek olanı yapın. Ardından etkileşimli olarak yeniden adlandırın ve ilkini silin.
funroll

5
Sen kullanarak sonuçlardan, bu tür Git gibi, bir dizin hariç tutabilir -path ./.git -prune -oiçinde find . -path ./.git -prune -o -type f -name '*matchThisText*' -print0Xargs Borulama önce
devinbost

Yanıtlar:


850
find /home/www \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'

-print0findsonuçların her birini yeni bir satır yerine boş bir karakterle yazdırmayı söyler . Dizininizin adlarında yeni satır içeren dosyalar olması olası olmayan bir durumda, bu yine xargsde doğru dosya adları üzerinde çalışmanıza izin verir .

\( -type d -name .git -prune \)adlı tüm dizinleri tamamen atlayan bir ifadedir .git. SVN kullanıyorsanız veya korumak istediğiniz başka klasörleriniz varsa kolayca genişletebilirsiniz - sadece daha fazla adla eşleştirin. Kabaca eşdeğer -not -path .git, ancak daha verimlidir, çünkü dizindeki her dosyayı kontrol etmek yerine, dosyayı tamamen atlar. -oOndan sonra çünkü nasıl gereklidir -prunegerçekten çalışıyor.

Daha fazla bilgi için, bkz man find.


132
OSX'te sorunla karşılaşabilirsiniz sed: 1: "...": invalid command code .. Görünüşe göre -i seçeneği uzantıyı bekliyor ve 's/../...'komutun ayrıştırılmasını sağlıyor . Çözüm: '' -i seçeneği gibi uzantıyı geçirin sed -i '' 's/....
Robert Lujo

6
Not: Bunu bir dizin üzerinde kullanırsanız ve neden svn stdeğişiklik göstermediğini merak ediyorsanız, bunun nedeni .svn dizinlerindeki dosyaları da değiştirmiş olmanızdır! find . -maxdepth 1 -type f -print0 | xargs -0 sed -i 's/toreplace/replaced/g'Bunun yerine kullanın .
ACK_stoverflow

57
Ayrıca, git deposundaysanız dikkatli olun. Açık bir dalda test ederek akıllı olduğumu düşündüm, bu yüzden kötü bir şey yaptıysa geri dönebilirdim, ancak bunun yerine git dizinimi bozdum.
Ciryon

13
grep -r 'hello' -l --null . | xargs -0 sed -i 's#hello#world#g'İlişkisiz dosyaları düzenlemekten kaçınmak için bunu kullanın (sed dosya kodlamasını değiştirebilir).
caiguanhao

6
"ancak bunun yerine git dizinimi bozdum." Bu konuda çok fazla endişelenmeyin find .git ... | ... 'sed -i s/(the opposite from before)/g', git dizini düzeltmek için yapabilirsiniz
Massey101

259

Not : Bu komutu git repo içeren bir klasörde çalıştırmayın; .git'deki değişiklikler git dizininizi bozabilir.

find /home/www/ -type f -exec \
    sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g' {} +

Buradaki diğer cevaplarla karşılaştırıldığında, bu çoğudan daha basittir ve orijinal sorunun sorduğu perl yerine sed kullanır.


50
BSD sed kullanıyorsanız (Mac OS X dahil) sed -iseçeneğine açık bir boş dize argümanı vermeniz gerektiğini unutmayın . ie: sed -i '' 's/original/replacement/g'
Nathan Craike

2
@JohnZwinck Benim hatam, + 'ı kaçırdı. Tuhaf bir şekilde, Nikita'nın çözümü benim için daha hızlı çalışıyor.
Sam

6
@AoeAoe: Ortaya +çıkan sedsüreçlerin sayısını büyük ölçüde azaltır . Daha verimlidir.
John Zwinck

4
Git deposu olan bir klasörde bunu nasıl güvenle yapabilirim?
Hatshepsut

20
Bu sizin bulmak sonuçlarından repo hariç tutuyorsa git repo içeren bir klasörü yürütmek için güvenli: find . -not -path '*/\.git*' -type f ....
Dale Anderson

211

Benim için en basit yol

grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'

1
@Anatoly: sadece bir soru: İkili dosyaları (yürütülebilir dosyalar) nasıl hariç tutabilirim ?
user2284570

3
@ user2284570 -Iveya --binary-file=without-matchgrep bayraklarını kullanın .
Zéychin

34
Bu, gibi dizinleri hariç tutmanız gerektiğinde özellikle iyi çalışır .svn. Örneğin:grep -rl oldtext . --exclude-dir=.svn | xargs sed -i 's/oldtext/newtext/g'
phyatt

11
brew install gnu-sedve gsedacı dünyasından kaçınmak için OSX'te kullanın.
ı p

1
adamlar Projeniz git sürüm bilgisi ise, bunun yerine bunu kullanın, dikkat lütfen: git grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'. .gitdir f * ck kadar hiç hoş değil
Paolo

61

Tüm püf noktaları neredeyse aynı, ama bunu beğendim:

find <mydir> -type f -exec sed -i 's/<string1>/<string2>/g' {} +
  • find <mydir>: dizinde arama.

  • -type f:

    Dosya türü: normal dosya

  • -exec command {} +:

    -Exec eyleminin bu değişkeni, seçilen dosyalarda belirtilen komutu çalıştırır, ancak komut satırı, seçilen her dosya adı sonuna eklenerek oluşturulur; komutun toplam çağrı sayısı, eşleşen dosya sayısından çok daha az olacaktır. Komut satırı, xargs'ın komut satırlarını oluşturduğu gibi oluşturulur. Komutta yalnızca bir {{} örneğine izin verilir. Komut başlangıç ​​dizininde yürütülür.


-exec ile @ user2284570? Araç adı yerine yürütülebilir dosyanın yolunu ayarlamayı deneyin.
I159

@ I159: Hayır: yürütülebilir ikili dosyaları hariç tutar (ancak kabuk komut dosyalarını içerir) .
user2284570

8
@ I159 Bu cevap John Zwinck'inki ile aynı değil mi?
Monica'yı eski

1
@ user2284570 "İkili dosya" kavramı tam olarak tanımlanmamıştır. fileHer dosyanın türünü belirlemeye çalışmak için komutu kullanabilirsiniz , ancak çıktısındaki gelişigüzel varyasyonları biraz şaşırtıcı olabilir. -I(Aka --mime) seçeneği biraz yardımcı olur, ya --mime-typeo varsa. Bunu yapmak için bu temiz tek astarı tam olarak nasıl yeniden düzenlemek, bu küçük yorum kutusu için üzücü. Yardıma ihtiyacınız varsa belki ayrı bir soru gönderin? (Belki o zaman buraya bağlantı içeren bir yorum ekleyin.)
tripleee

1
en temiz cevap! teşekkürler dostum
jukerok

39
cd /home/www && find . -type f -print0 |
  xargs -0 perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g'

2
Ben, kullanmak için bir sebep yoktur meraklıyım -print0ve xargsyerine -execya -execdir?
Philipp

4
Orada: from "man find": Belirtilen komut her eşleşen dosya için bir kez çalıştırılır. Yani, / home / www içinde 2000 dosya varsa, 'find ... -exec ...' 2000 perl çağrısına neden olur; oysa bul ... | xargs ... 'perl'i yalnızca bir veya iki kez çağırır (ARG_MAX yaklaşık 32K ve ortalama dosya adı uzunluğu 20 olduğu varsayılarak).
Rus

2
@Employed Russian: bu yüzden kullanacaksınız find -exec command {} +- xargs gibi komutun aşırı çağrılmasını önler, ancak ayrı bir işlem olmadan.
John Zwinck

2
Hangi platformda? Xargs çözümü taşınabilir, bulunan "find ... -exec" "sihirli" çağrıları bulunan her dosya için bir alt işlem çağırmayın değildir.
Rus

4
@EmployedRussian, find -exec ... {} +2006 yılından beri POSIX olarak belirlendi.
Charles Duffy

34

Benim için hatırlanması en kolay çözüm https://stackoverflow.com/a/2113224/565525 , yani:

sed -i '' -e 's/subdomainA/subdomainB/g' $(find /home/www/ -type f)

NOT : -i ''OSX sorununu çözersed: 1: "...": invalid command code .

NOT : İşlenecek çok fazla dosya varsa alacaksınız Argument list too long. Geçici çözüm - yukarıda açıklanan kullanım find -execveya xargsçözüm.


4
workaroundHer durumda tercih sözdizimi olmalıdır.
Reinstate Monica Lütfen

1
Komut ikamesi ile ilgili sorun $(find...), kabuğun boşlukları veya diğer kabuk metakarakterleriyle dosya adlarını işlemesi için bir yol olmamasıdır. Eğer varsa bilmek bu bir sorun değildir, bu yaklaşım gayet iyi; ancak insanların bu konuda uyarılmadığı veya uyarıyı anlamadığı çok fazla soru var.
üçlü

30

Gümüş arama yapan herkes için ( ag)

ag SearchString -l0 | xargs -0 sed -i 's/SearchString/Replacement/g'

Ag, git / hg / svn dosyasını / klasörlerini varsayılan olarak yok saydığından, bu bir havuzun içinde çalışmak güvenlidir.


16

Ekstra bir güzel oneliner. Git grep kullanma.

git grep -lz 'subdomainA.example.com' | xargs -0 perl -i'' -pE "s/subdomainA.example.com/subdomainB.example.com/g"

3
.Git / content üzerine yazma riski taşımadığınız için git repo içinde çalışıyorsanız iyi bir fikirdir (yorumlarda başka bir cevaba bildirildiği gibi).
mahemoff

1
Teşekkürler, refactor() { echo "Replacing $1 by $2 in all files in this git repository." git grep -lz $1| xargs -0 perl -i'' -pE "s/$1/$2/g" }örneğin 'kelime' yerine 'kılıç' yerine bir bash işlevi Kullanımı olarak kullanıyorum : refactor word swordsonra ne yaptığını doğrulayın git diff.
Paul Rougieux

16

Dosyaları yinelemeli olarak kesmek için dize örneğiniz için sedşunları yapabilirsiniz grep:

grep -rl <oldstring> /path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g

Çalıştırırsanız , .git dizinlerinde aramayı atlamak ve diğerlerinin kibarca işaret ettiği gibi git endeksi sorunlarından kaçınmak isterseniz man grepbir --exlude-dir="*.git"bayrak tanımlayabileceğinizi fark edeceksiniz .

Sizi yönlendiren:

grep -rl --exclude-dir="*.git" <oldstring> /path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g

13

Bu git depolarıyla uyumlu ve biraz daha basit:

Linux:

git grep -l 'original_text' | xargs sed -i 's/original_text/new_text/g'

Mac:

git grep -l 'original_text' | xargs sed -i '' -e 's/original_text/new_text/g'

( Http://blog.jasonmeridth.com/posts/use-git-grep-to-replace-strings-in-files-in-your-git-repository/ sayesinde )


Bilge kullanmak git-grep'ın -zbirlikte seçeneği xargs -0.
gniourf_gniourf

git grepAçıkçası sadece bir gitrepoda mantıklı . Genel değiştirme olurdu grep -r.
Üçlü

@gniourf_gniourf Açıklayabilir misiniz?
Petr Peller

2
@PetrPeller: ile -z, git-grepçıkış alanlarını yeni satırlar yerine boş baytlarla ayırır; ile birlikte -0, xargsboşluklar yerine boş baytlarla ayrılmış girdiyi okuyacaktır (ve tırnak işaretleri ile garip şeyler yapmayın). Dosya isimleri boşluk, tırnak veya diğer komik karakterler içeren eğer mola için komut istemiyorsanız Yani, komut: git grep -z -l 'original_text' | xargs -0 sed ....
gniourf_gniourf

10
find /home/www/ -type f -exec perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g' {} +

find /home/www/ -type f / home / www / (ve alt dizinlerindeki) tüm dosyaları listeler. "-Exec" bayrağı, bulmanın bulunan her dosyada aşağıdaki komutu çalıştırmasını söyler.

perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g' {} +

dosyalarda çalıştırılan komuttur (bir seferde birçok). {}Dosya adlar geçer alır. +Komutun sonunda anlatır findbirçok dosya adları için bir komut inşa etmek.

Başına findadam sayfası: "komut satırı Xargs onun komut satırları kurar kadar aynı şekilde inşa edilmiştir."

Böylece xargs -0, veya kullanmadan hedefinize ulaşmak (ve boşluk içeren dosya adlarını işlemek) mümkündür -print0.


8

Sadece buna ihtiyacım vardı ve mevcut örneklerin hızından memnun değildim. Ben de kendim geldim:

cd /var/www && ack-grep -l --print0 subdomainA.example.com | xargs -0 perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g'

Ack-grep, ilgili dosyaları bulmada çok etkilidir. Bu komut ~ 145 000 dosyayı bir esinti ile değiştirirken, diğerleri çok uzun sürdü ve bitene kadar bekleyemedim.


Güzel, ama grep -ril 'subdomainA' *hiçbir yere kadar hızlı değil grep -Hr 'subdomainA' * | cut -d: -f1.
trusktr

@Henno: sadece bir soru: İkili dosyaları (yürütülebilir dosyalar) nasıl hariç tutabilirim ?
user2284570

ack-grep bunu sizin için otomatik olarak yapar.
Henno

@Henno: Kabuk betikleri içeriyor mu?
user2284570

Evet. Desteklediği dosya türlerinin tam listesi: beyondgrep.com/documentation
Henno

6

Dizinleri ( --exclude-dir=.svn) hariç tutmanız gerekiyorsa ve ayrıca boşluklu dosya adlarına sahip olabilirseniz ( grep -Zve ile 0Byte kullanarak)xargs -0

grep -rlZ oldtext . --exclude-dir=.svn | xargs -0 sed -i 's/oldtext/newtext/g'

6

Değiştirmenin en basit yolu ( tüm dosyalar, dizin, özyinelemeli )

find . -type f -not -path '*/\.*' -exec sed -i 's/foo/bar/g' {} +

Not: Bazen bazı gizli dosyaları göz ardı etmeniz gerekebilir .git, yani yukarıdaki komutu kullanabilirsiniz.

Gizli dosyaları kullanmak istiyorsanız,

find . -type f  -exec sed -i 's/foo/bar/g' {} +

Her iki durumda da dize fooyeni dize ile değiştirilirbar


5

grep -lr 'subdomainA.example.com' | while read file; do sed -i "s/subdomainA.example.com/subdomainB.example.com/g" "$file"; done

Sanırım çoğu insan bir şeyleri "okuma dosyası" haline getirebileceklerini bilmiyor ve dosya adlarındaki boşlukları önceden korurken bu kötü -print0 argümanlarından kaçınıyor.

Ayrıca echosed'den önce bir ekleme yapmak, gerçekte yapmadan önce hangi dosyaların değişeceğini görmenizi sağlar.


Bunun nedeni -print0, işlenemeyen durumları while readişlemesi - yeni satır, Unix dosya adında geçerli bir karakterdir, bu nedenle kodunuzun tamamen sağlam olması için, bu tür dosya adlarıyla da başa çıkması gerekir. (Ayrıca, read -rbazı sinir bozucu POSIX eski davranışlardan kaçınmak istersiniz read.)
tripleee

Ayrıca, sedeşleşme yoksa bir hayır-op, bu yüzden grepgerçekten gerekli değildir; ancak, çok fazla eşleşmeniz varsa veya dosyalardaki tarih damgalarının gereksiz yere güncellenmesini önlemek istiyorsanız, herhangi bir eşleşme içermeyen dosyaları yeniden yazmaktan kaçınmak için yararlı bir optimizasyon.
tripleee

5

Bunu aşağıdaki gibi çözmek için awk kullanabilirsiniz,

for file in `find /home/www -type f`
do
   awk '{gsub(/subdomainA.example.com/,"subdomainB.example.com"); print $0;}' $file > ./tempFile && mv ./tempFile $file;
done

Bu size yardımcı olacağını umuyoruz !!!


Herhangi bir sorun olmadan MacO'lar üzerinde çalışır! sedOsx'a özgü ayarlarda bile ikili dosyalar dahil edildiğinde tüm tabanlı komutlar başarısız oldu.
Jankapunkt

Dikkatli olun ... Bu, dosya finddönüşlerinden herhangi birinin adlarında bir boşluk varsa patlar! Kullanımı çok daha güvenli while read: stackoverflow.com/a/9612560/1938956
Soren Bjornstad

4

Bunu dene:

sed -i 's/subdomainA/subdomainB/g' `grep -ril 'subdomainA' *`

1
Merhaba @RikHic, güzel ipucu - böyle bir şey düşünüyordum; ne yazık ki yukarıdaki biçimlendirme tam olarak doğru değildi :) Bu yüzden bir ön etiketi ile çalışacağım (işe yaramaz) - bu yüzden kaçan backticks ile: sed -i 's/subdomainA/subdomainB/g'` grep -ril 'subdomainA' /home/www/*` - bu hala çok iyi görünmüyor, ancak kopya macunu hayatta :) Şerefe!
sdaau

4
#!/usr/local/bin/bash -x

find * /home/www -type f | while read files
do

sedtest=$(sed -n '/^/,/$/p' "${files}" | sed -n '/subdomainA/p')

    if [ "${sedtest}" ]
    then
    sed s'/subdomainA/subdomainB/'g "${files}" > "${files}".tmp
    mv "${files}".tmp "${files}"
    fi

done

4

Göre bu blog yayınına:

find . -type f | xargs perl -pi -e 's/oldtext/newtext/g;'

Eğik çizgilerden nasıl kaçıyorsun /? Örneğin, IP adreslerini değiştirmek istiyorum: xxx.xxx.xxx.xxxforxxx.xxx.xxx.xxx/folder
Pathros

/\ İle kaçabilirsiniz . Örneğin:find . -type f | xargs perl -pi -e 's/xxx.xxx.xxx.xxx\/folder/newtext/g;'
J.Hpour

3

Veya araçlarıyla vimbirlikte kullanmanın bir sakıncası grepyoksa find, Gert kullanıcısı tarafından verilen bu bağlantıda verilen cevabı takip edebilirsiniz -> Büyük bir klasör hiyerarşisinde metin değişimi nasıl yapılır? .

İşte anlaşma:

  • belirli bir yolda değiştirmek istediğiniz dizeyi özyinelemeli olarak grep ve eşleşen dosyanın yalnızca tam yolunu alır. (bu olurdu $(grep 'string' 'pathname' -Rl).

  • (isteğe bağlı) merkezi dizindeki bu dosyaların ön yedeğini almak istiyorsanız, bunu da kullanabilirsiniz: cp -iv $(grep 'string' 'pathname' -Rl) 'centralized-directory-pathname'

  • bundan sonra, vimverilen bağlantıda sağlanan şemaya benzer bir şemayı izleyerek istediğiniz zaman düzenleyebilir / değiştirebilirsiniz :

    • :bufdo %s#string#replacement#gc | update

2

Biraz eski okul ama bu OS X üzerinde çalıştı.

Birkaç hile var:

• Yalnızca .slsgeçerli dizinin altındaki uzantıya sahip dosyaları düzenler

• "herhangi bir karakter" olarak değerlendirilmediğinden .emin olmak için kaçmalıdırsed

• normal yerine ayırıcı ,olarak kullanılırsed/

Ayrıca bunun bir Jinja şablonunu bir variableyoldan geçmek için düzenlemek olduğuna dikkat edin import(ancak bu konu dışıdır).

İlk olarak, sed komutunuzun istediğinizi yaptığını doğrulayın (bu yalnızca stdout'taki değişiklikleri yazdırır, dosyaları değiştirmez):

for file in $(find . -name *.sls -type f); do echo -e "\n$file: "; sed 's,foo\.bar,foo/bar/\"+baz+\"/,g' $file; done

Değişiklik yapmaya hazır olduğunuzda sed komutunu gerektiği gibi düzenleyin:

for file in $(find . -name *.sls -type f); do echo -e "\n$file: "; sed -i '' 's,foo\.bar,foo/bar/\"+baz+\"/,g' $file; done

Not -i ''içinde sed I (açıklandığı şekilde orijinal dosyaların yedeğini oluşturmak istemedim, komuta OS X üzerinde sed ile In-yer düzenlemeleri bu sayfadaki veya Robert Lujo en yorumunda).

Mutlu acılar millet!


2

sadece değişmemek için

  • NearlysubdomainA.example.com
  • subdomainA.example.comp.other

ama hala

  • subdomainA.example.com.IsIt.good

(alan adı kökü arkasındaki fikirde iyi olmayabilir)

find /home/www/ -type f -exec sed -i 's/\bsubdomainA\.example\.com\b/\1subdomainB.example.com\2/g' {} \;

2

Sadece üstleri kullanıyorum:

find . -name '*.[c|cc|cp|cpp|m|mm|h]' -print0 |  xargs -0 tops -verbose  replace "verify_noerr(<b args>)" with "__Verify_noErr(<args>)" \
replace "check(<b args>)" with "__Check(<args>)" 

artı bir `` *. [c | cc | cp | cpp | m | mm | h] ''
FractalSpace

2

İşte birçoğundan daha genel olması gereken bir sürüm; örneğin find( dubunun yerine) gerektirmez . Sadece xargsPlan 9'un bazı sürümlerinde (9front gibi) bulunan gerektirir.

 du -a | awk -F' '  '{ print $2 }' | xargs sed -i -e 's/subdomainA\.example\.com/subdomainB.example.com/g'

Dosya uzantıları gibi filtreler eklemek istiyorsanız şunu kullanın grep:

 du -a | grep "\.scala$" | awk -F' '  '{ print $2 }' | xargs sed -i -e 's/subdomainA\.example\.com/subdomainB.example.com/g'

1

IBM tarafından Qshell (qsh) için, OP tarafından etiketlendiği gibi bash değil.

Qsh komutlarının sınırlamaları:

  • find -print0 seçeneğine sahip değil
  • xargs -0 seçeneğine sahip değil
  • sed -i seçeneği yok

Böylece qsh içindeki çözüm:

    PATH='your/path/here'
    SEARCH=\'subdomainA.example.com\'
    REPLACE=\'subdomainB.example.com\'

    for file in $( find ${PATH} -P -type f ); do

            TEMP_FILE=${file}.${RANDOM}.temp_file

            if [ ! -e ${TEMP_FILE} ]; then
                    touch -C 819 ${TEMP_FILE}

                    sed -e 's/'$SEARCH'/'$REPLACE'/g' \
                    < ${file} > ${TEMP_FILE}

                    mv ${TEMP_FILE} ${file}
            fi
    done

Uyarılar:

  • Çözüm hata işlemeyi hariç tutar
  • OP tarafından etiketlendiği gibi değil Bash

Bu alıntılar yanı sıra okuma satırları ile bazı sinir bozucu sorunları var for .
tripleee

1

Bunu SVN deponuzu tamamen yok etmeden kullanmak istiyorsanız, 'find' komutunu kullanarak tüm gizli dosyaları yok saymayı söyleyebilirsiniz:

find . \( ! -regex '.*/\..*' \) -type f -print0 | xargs -0 sed -i 's/subdomainA.example.com/subdomainB.example.com/g'

Parantez gereksiz görünüyor. Bu daha önce kullanılamayan bir biçimlendirme hatası içeriyordu (Markdown oluşturma işlemi normal ifadeden bazı karakterleri yerlerdi).
tripleee

1

Kombinasyonunu kullanarak grepvesed

for pp in $(grep -Rl looking_for_string)
do
    sed -i 's/looking_for_string/something_other/g' "${pp}"
done

@tripleee Bunu biraz değiştirdim. Bu durumda grep -Rl pattern, desenin olduğu dosyaların komut tarafından oluşturulan listesi için çıktı . Dosyalar fordöngüde okunmaz .
Pawel

Ha? Hala bir fordöngü var; döndürülen herhangi bir dosya adı boşluk içeriyorsa, kabuk forbağımsız değişken listesini belirttiği için düzgün çalışmaz . Ancak daha sonra dosya adı değişkenini döngü içinde tırnak işaretleri olmadan kullanırsınız, bu nedenle bunu düzeltirseniz bunun yerine kırılır. Kalan bu hataları düzeltmek, sizinkinin @ MadMan2064'ün cevabı ile aynı olmasını sağlayacaktır.
tripleee

@tripleee evet, bu doğru, bunu kaçırdım.
Pawel

1

Git deposundaki tüm oluşumları değiştirmek için şunları kullanabilirsiniz:

git ls-files -z | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'

Bkz. Dosyaları yerel git repo'da listeleme? havuzdaki tüm dosyaları listeleyen diğer seçenekler için. -zSeçenekler güvence veriyor o sıfır byte ile dosya adlarını ayırmak için git söyler xargs(seçeneğiyle -0onlar boşluk durumlarda ne içerse bile) dosya ayırabilirsiniz.


1
perl -p -i -e 's/oldthing/new_thingy/g' `grep -ril oldthing *`

1
awk/ Kullanmamak sed, ancak perl yaygındır (yalnızca meşgul kutulu / gömülü sistemler hariç).
pevik

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.