Komutları kullanarak bir dosya içindeki metni bul ve değiştir

433

Belirli bir kelimeyi komut satırını kullanarak bir metin dosyasında nasıl bulabilir ve değiştirebilirim?

    
sordu Jon Doe 07.01.2011 05:10

7 cevap

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

Açıklama:

  • sed = Akış Editörü
  • -i = yerinde (yani, orijinal dosyaya geri kaydet)
  • Komut dizesi:

    • s = yedek komut
    • original = değiştirilecek kelimeyi (veya yalnızca kelimenin kendisini) açıklayan normal bir ifade
    • new = ile değiştirilecek metin
    • g = global (yani, yalnızca ilk yeri değil, tümünü değiştirin)
  • file.txt = dosya adı

verilen cevap cscarney 07.01.2011 05:23
26

Bunu yapmak için farklı yollar vardır. Biri sed ve Regex kullanıyor. SED, metni filtrelemek ve dönüştürmek için bir Akış Editörü. Bir örnek şu şekildedir:

[email protected]: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orly
[email protected]: ~$ sed s/slow/quick/ < orly > yarly
[email protected]: ~$ cat yarly
The quick brown unicorn jumped over the hyper sleeping dog

< strin ve > strout değerinden daha mantıklı olabilecek başka bir yol da borularla!

[email protected]: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowai
[email protected]: ~$ cat nowai 
The quick brown fox jumped over the lazy sleeping dog
    
verilen cevap Marco Ceppi 07.01.2011 05:26
15

Vim'i Ex modunda kullanabilirsiniz:

ex -sc '%s/OLD/NEW/g|x' file
  1. % tüm satırları seç

  2. s ödevi

  3. g , her satırdaki tüm örnekleri değiştirir

  4. x değişiklik yapıldıysa (sahip olduklarında) yazıp çık

verilen cevap Steven Penny 16.04.2016 20:36
14

Awk'in gsub komutuyla

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

Örnek:

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

Yukarıdaki örnekte, tüm 1'ler, bulunduğu yere bakılmaksızın 0 ile değiştirilir.

Belirli bir sütunda yeni bir değişiklik yapmak isterseniz bunu yapın

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

Örnek:

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

1 ile yalnızca 1 sütununda 1 değiştirir.

Perl ile,

$ echo 'foo' | perl -pe 's/foo/bar/g'
bar
    
verilen cevap Avinash Raj 02.07.2014 14:59
12

Bunu başarmanın birçok yolu var. Dize değişimi ile neyin başarılmasının karmaşıklığına bağlı olarak ve kullanıcının tanıdık olduğu araçlara bağlı olarak, bazı yöntemler diğerlerinden daha fazla tercih edilebilir.

Bu yanıtta, burada verilen tüm örnekleri test etmek için kullanabileceğiniz basit input.txt dosyasını kullanıyorum. Dosya içeriği:

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

BASH

Bash gerçekten metin işlemeye yönelik değildir, ancak basit ikameler özellikle parametre genişletme aracılığıyla yapılabilir. Basit yapı ${parameter/old_string/new_string} kullanabiliriz.

#!/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

Bu küçük betik yerinde bir değişiklik yapmaz, yani yeni metni yeni dosyaya kaydetmek ve eski dosyadan kurtulmak veya mv new.txt old.txt

Yan not: while IFS= read -r ; do ... done < input.txt 'nin neden kullanıldığını merak ediyorsanız, temelde dosyanın dosya satırını okuma kabuğunun temelini oluşturur. Referans için bu sayfasına bakın.

AWK

AWK, bir metin işleme aracı olmak gibi bir görev için oldukça uygun. Düzenli ifadelere dayanarak basit değiştirmeler ve çok daha gelişmiş olanları yapabilir. İki işlev sağlar: sub() ve gsub() . Birincisi sadece ilk oluşumu değiştirir, ikincisi ise - bütün dizgede gerçekleşen olayların yerini alır. Örneğin, one potato two potato dizesi varsa, sonuç şöyle olur:

$ 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 bir giriş dosyasını argüman olarak alabilir, bu yüzden input.txt ile aynı şeyi yapmak kolay olurdu:

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

Sahip olduğunuz AWK sürümüne bağlı olarak, yerinde düzenleme yapabilir veya olmayabilir, dolayısıyla normal uygulama yeni metni kaydedip değiştirir. Mesela şöyle bir şey:

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

SED

Sed bir satır editörüdür. Ayrıca normal ifadeler kullanır, ancak basit ikameler için yapmanız yeterlidir:

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

Bu araçla ilgili iyi olan şey, -i bayrağıyla etkinleştirebileceğiniz yerinde düzenlemeye sahip olmasıdır.

Perl

Perl, metin işleme için sıklıkla kullanılan başka bir araçtır, ancak genel amaçlı bir dildir ve ağ oluşturma, sistem yönetimi, masaüstü uygulamaları ve diğer pek çok yerde kullanılır. C, sed, awk ve diğerleri gibi diğer dillerden birçok kavram / özellik ödünç aldı. Basit ikame şöyle yapılabilir:

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

Sed gibi, perl'de de -i bayrağı var.

Python

Bu dil çok yönlüdür ve ayrıca çok çeşitli uygulamalarda kullanılır. Dizeleri ile çalışmak için çok fazla işlevi vardır, bunların replace() 'si, yani var="Hello World" gibi bir değişkeniniz varsa, var.replace("Hello","Good Morning")

yapabilirdiniz

Dosyanın okunması ve içindeki dizinin değiştirilmesi için basit bir yol şöyle olurdu:

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

Bununla birlikte, Python ile, ayrıca senaryonun içinden de yapabileceğiniz yeni bir dosyaya çıktı almanız gerekir. Örneğin, basit bir tane:

#!/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])

Bu komut dosyası, komut satırı argümanı olarak input.txt ile çağrılmalıdır.

Python da düzenli ifadelere sahip olabilir, özellikle re işlevine sahip re.sub() modülünde daha gelişmiş yedeklemeler için kullanılabilir.

    
verilen cevap Sergiy Kolodyazhnyy 03.02.2017 08:49
6

sed , s akış yönündedir ed itor , | yoluyla standart akışları (STDIN ve STDOUT özel olarak) göndermek için sed (pipe) kullanabilir ve bunları programatik olarak programatik olarak değiştirebilirsiniz. uçmak, Unix felsefesi geleneğinde kullanışlı bir araç yapmak; ancak, aşağıda belirtilen -i parametresini kullanarak dosyaları doğrudan düzenleyebilir.
Aşağıdakileri düşünün :

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

s/ , few ile bulunan asd ifadesini bulundu:

s için kullanılır:

  

Birkaç, cesur.

     

Asd, cesur.

/g , tüm satır için bunu yapmak için "global" anlamına gelir. % Co_de% 'yi ( /g ile, ne olursa olsun her zaman üç eğik çizgi olması gerekir) ve s/few/asd/ aynı satırda iki kez görünürse, yalnızca ilk few ' si few olarak değiştirilir:

  

Birkaç erkek, birkaç kadın, cesur.

     

Asd adamları, birkaç kadın, cesur.

Bu, bazı durumlarda, satırların başlangıcında özel karakterlerin değiştirilmesi gibi yararlıdır (örneğin, bazı kişilerin daha sonra e-posta ipliklerinde e-posta ipliklerinde önceki malzemeyi alıntılamak için kullandıkları sembollerin yerine, daha sonra alıntılanmış bir cebirsel eşitsizlikten ayrılırlar. el değmemiş satırda), ancak her yerde asd oluştuğunu belirttiğiniz örneğinizde, değiştirilmesi gerekir, bu% co_de değerine sahip olduğunuzdan emin olun.

Aşağıdaki iki seçenek (bayrak) bir, few şeklinde birleştirilir:

/g seçeneği, -ie dosyasındaki i n yerini düzenlemek için kullanılır.

-i seçeneği, e xpression / command komutunu çalıştırır. Bu durumda hello.txt .

Not: Arama yapmak / değiştirmek için -e kullanmanız önemlidir. % Co_de% yaparsanız, 'e' harfi eklenmiş her dosyanın yedeğini oluşturursunuz.

    
verilen cevap Chaminda Bandara 23.11.2017 10:00
0

Bunu şu şekilde yapabilirsiniz:

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

Örnekler: [logdir ',' '] ([) olmadan [logdir', os.getcwd ()] ile tüm oluşumları yer belirleme komutunun sonucu olan tüm dosyalarda değiştirmek için:

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

[tensorboard / program.py] dosyasının aranacağı yer

    
verilen cevap Nguyễn Tuấn Anh 24.07.2018 04:13

Etiketlerdeki diğer soruları oku