Sed Komutu Linux'ta Nasıl Kullanılır

Çılgınca gelebilir, ancak Linux sedkomutu arabirimi olmayan bir metin düzenleyicidir. Dosyalardaki ve akışlardaki metni işlemek için komut satırından kullanabilirsiniz. Size gücünü nasıl kullanacağınızı göstereceğiz.

Sed'in Gücü

sed(Pratiğin en azından bir sürü veya) bunları usta temellerini ve bir ömür öğrenmek için bir saat sürer: Komut satranç gibi biraz. Ana sedişlev kategorilerinin her birinde size açılış bahislerinden bir seçim göstereceğiz .

sedborulu giriş veya metin dosyaları üzerinde çalışan bir akış düzenleyicidir. Bununla birlikte, etkileşimli bir metin düzenleyici arayüzüne sahip değildir. Bunun yerine, metin içinde çalışırken izlemesi için talimatlar veriyorsunuz. Bunların tümü Bash ve diğer komut satırı kabuklarında çalışır.

İle sedaşağıdakilerin tümünü yapabilirsiniz:

  • Metin seç
  • İkame metin
  • Metne satır ekle
  • Metinden satırları sil
  • Orijinal bir dosyayı değiştirin (veya koruyun)

Örneklerimizi, kavramları tanıtmak ve göstermek için yapılandırdık, en kısa (ve en az yaklaşılabilir) sedkomutları üretmek için değil . Bununla birlikte, örüntü eşleştirme ve metin seçimi işlevleri sed büyük ölçüde normal ifadelere (regexes) dayanır. En iyi şekilde yararlanmak için bunlara aşina olmanız gerekecek sed.

İLGİLİ: Linux'ta Normal İfadeler (regexes) Nasıl Kullanılır

Basit Bir Örnek

İlk olarak, borudan bir echometin göndermek için kullanacağız ve metnin  bir kısmını değiştireceğiz. Bunu yapmak için aşağıdakileri yazıyoruz:sedsed

echo howtogonk | sed 's / gonk / geek /'

echoKomut içine “howtogonk” gönderir sedve bizim basit ikame kuralı ( “s” ikame açılımı) uygulanır. sed Giriş metninde ilk dizenin geçtiği yeri arar ve eşleşmeleri ikinciyle değiştirir.

"Gonk" dizesi "geek" ile değiştirilir ve yeni dizi terminal penceresinde yazdırılır.

Değişiklikler muhtemelen en yaygın kullanımdır sed. Değişimleri daha derinlemesine incelemeden önce, metni nasıl seçip eşleştireceğimizi bilmemiz gerekir.

Metin Seçme

Örneklerimiz için bir metin dosyasına ihtiyacımız olacak. Samuel Taylor Coleridge'in destansı şiiri The Rime of the Ancient Mariner'dan bir seçki içeren bir şiir kullanacağız.

Buna bir göz atmak için aşağıdakileri yazıyoruz less:

daha az coleridge.txt

Dosyadan bazı satırları seçmek için, seçmek istediğimiz aralığın başlangıç ​​ve bitiş satırlarını sağlıyoruz. Tek bir numara, o satırı seçer.

Birden dörde kadar olan satırları çıkarmak için şu komutu yazıyoruz:

sed -n '1,4p' coleridge.txt

Arasındaki virgül Not 1ve 4. pVasıta “eşleşti satırları yazdırmak.” Varsayılan olarak  sed tüm satırları yazdırır. Dosyadaki tüm metni eşleşen satırlarla iki kez yazdırılmış olarak görürdük. Bunu önlemek -niçin, eşleşmeyen metni bastırmak için (sessiz) seçeneğini kullanacağız.

Satır numaralarını aşağıda gösterildiği gibi farklı bir dize seçebilmemiz için değiştiriyoruz:

sed -n '6,9p' coleridge.txt

-eÇoklu seçim yapmak için (ifade) seçeneğini kullanabiliriz. İki ifadeyle, şu şekilde iki ayet seçebiliriz:

sed -n -e '1,4p' -e '31, 34p 'coleridge.txt

İkinci ifadede birinci sayıyı azaltırsak, iki ayet arasına bir boşluk koyabiliriz. Aşağıdakileri yazıyoruz:

sed -n -e '1,4p' -e '30, 34p 'coleridge.txt

Ayrıca bir başlangıç ​​satırı seçip sed dosyada adım adım ilerlemeyi ve her beş satırda bir alternatif satırlar yazdırmayı veya herhangi bir sayıda satırı atlamayı söyleyebiliriz . Komut, yukarıda bir aralık seçmek için kullandıklarımıza benzer. Ancak bu sefer ~sayıları ayırmak için virgül yerine tilde ( ) kullanacağız .

İlk sayı başlangıç ​​çizgisini gösterir. İkinci sayı sed, başlangıç ​​çizgisinden sonraki hangi satırları görmek istediğimizi söyler . 2 sayısı her ikinci satır anlamına gelir, 3 her üçüncü satır anlamına gelir vb.

Aşağıdakileri yazıyoruz:

sed -n '1 ~ 2p' coleridge.txt

Dosyada aradığınız metnin nerede olduğunu her zaman bilemezsiniz, bu da satır numaralarının her zaman pek yardımcı olmayacağı anlamına gelir. Bununla birlikte, sed eşleşen metin desenleri içeren satırları seçmek için de kullanabilirsiniz . Örneğin, "Ve" ile başlayan tüm satırları çıkaralım.

Düzeltme işareti ( ^) satırın başlangıcını temsil eder. Arama terimimizi eğik çizgiler ( /) içine alacağız . Ayrıca "And" dan sonra bir boşluk ekledik, böylece "Android" gibi kelimeler sonuca dahil edilmeyecek.

sedSenaryoları okumak ilk başta biraz zor olabilir. /p O yukarıda kullandığımız komutlar yaptığı gibi araçlar “baskı”. Aşağıdaki komutta ise, eğik çizgi ondan önce gelir:

sed -n '/ ^ Ve / p' coleridge.txt

Dosyadan "Ve" ile başlayan üç satır çıkarılır ve bizim için görüntülenir.

Değişiklikler Yapmak

İlk örneğimizde, size bir sedikame için aşağıdaki temel biçimi gösterdik :

echo howtogonk | sed 's / gonk / geek /'

Bunun  bir ikame olduğunu ssöyler sed. İlk dize, arama modeli ve ikincisi, bu eşleşen metni değiştirmek istediğimiz metindir. Tabii ki, Linux ile ilgili her şeyde olduğu gibi, şeytan ayrıntıda gizlidir.

"Gün" ün tüm oluşumlarını "hafta" olarak değiştirmek ve denizciye ve albatrosa bağlanmaları için daha fazla zaman vermek için aşağıdakileri yazıyoruz:

sed -n 's / gün / hafta / p' coleridge.txt

İlk satırda sadece ikinci "gün" oluşumu değiştirilir. Bunun nedeni sed, satır başına ilk maçtan sonra durmasıdır. Her satırdaki tüm eşleşmelerin işlenmesi için genel bir arama yapmak için aşağıda gösterildiği gibi ifadenin sonuna bir "g" eklemeliyiz:

sed -n 's / gün / hafta / gp' coleridge.txt

Bu, ilk satırdaki dörtten üçüyle eşleşiyor. İlk kelime "Gün" olduğundan ve sedbüyük / küçük harfe duyarlı olduğundan, bu örneğin "gün" ile aynı olduğunu düşünmez.

Büyük / i küçük harf duyarlılığını belirtmek için ifadenin sonunda komuta bir ekleyerek aşağıdakini yazıyoruz:

sed -n 's / gün / hafta / gip' coleridge.txt

Bu işe yarıyor, ancak her şey için büyük / küçük harf duyarlılığını her zaman açmak istemeyebilirsiniz. Bu durumlarda, kalıba özgü büyük / küçük harf duyarlılığı eklemek için bir normal ifade grubu kullanabilirsiniz.

Örneğin, karakterleri köşeli parantez ( []) içine alırsak , "bu karakter listesindeki herhangi bir karakter" olarak yorumlanırlar.

Aşağıdakileri yazıyoruz ve hem "Gün" hem de "gün" ile eşleştiğinden emin olmak için gruba "D" ve "d" yi dahil ediyoruz:

sed -n 's / [Gg] ay / hafta / gp' coleridge.txt

Değişiklikleri dosyanın bölümleriyle de kısıtlayabiliriz. Diyelim ki dosyamızın ilk ayette garip boşluklar var. İlk ayeti görmek için şu tanıdık emri kullanabiliriz:

sed -n '1,4p' coleridge.txt

İki boşluk arayacağız ve bunları bir ile değiştireceğiz. Bunu global olarak yapacağız, böylece eylem tüm hat boyunca tekrarlanacak. Açık olmak gerekirse, arama modeli boşluktur, boşluk yıldız işaretidir ( *) ve ikame dizesi tek bir boşluktur. Değiştirmeyi 1,4dosyanın ilk dört satırı ile sınırlar.

Bunların hepsini aşağıdaki komutta bir araya getirdik:

sed -n '1,4 s / * / / gp' coleridge.txt

Bu güzel çalışıyor! Arama düzeni burada önemli olan şeydir. Yıldız işareti ( *), boşluk olan önceki karakterin sıfır veya daha fazlasını temsil eder. Bu nedenle, arama modeli bir veya daha fazla boşluktan oluşan dizeleri arar.

Birden fazla boşluktan oluşan herhangi bir dizinin yerine tek bir boşluk koyarsak, dosyayı her kelime arasında tek bir boşluk olacak şekilde normal aralığa döndürürüz. Bu aynı zamanda bazı durumlarda tek bir boşluğun yerine tek bir boşluk koyacaktır, ancak bu hiçbir şeyi olumsuz etkilemeyecektir - yine de istediğimiz sonucu alacağız.

Aşağıdakini yazıp arama modelini tek bir alana indirirsek, neden iki boşluk eklememiz gerektiğini hemen anlayacaksınız:

sed -n '1,4 s / * / / gp' coleridge.txt

Yıldız işareti, önceki karakterin sıfır veya daha fazlasıyla eşleştiği için, boşluk olmayan her karakteri "sıfır boşluk" olarak görür ve yerine koyma işlemini uygular.

Bununla birlikte, arama modeline iki boşluk  sedeklersek, ikameyi uygulamadan önce en az bir boşluk karakteri bulmalıyız. Bu, boşluksuz karakterlerin dokunulmadan kalmasını sağlar.

Daha -eönce kullandığımız (ifade) 'yi kullanarak, aynı anda iki veya daha fazla yer değiştirme yapmamızı sağlayan aşağıdakileri yazıyoruz:

sed -n -e 's / hareket / flutter / gip' -e '/ okyanus / oluk / gip' coleridge.txt

;İki ifadeyi ayırmak için noktalı virgül ( ) kullanırsak aynı sonucu elde edebiliriz , şöyle ki:

sed -n 's / hareket / flutter / gip; s / okyanus / oluk / gip' coleridge.txt

Aşağıdaki komutta "günü" "hafta" ile değiştirdiğimizde, "iyi bir gün" ifadesindeki "gün" örneği de değiştirildi:

sed -n 's / [Gg] ay / hafta / gp' coleridge.txt

Bunu önlemek için, yalnızca başka bir desenle eşleşen çizgiler üzerinde değişiklik yapmayı deneyebiliriz. Komutu, başlangıçta bir arama modeline sahip olacak şekilde değiştirirsek, yalnızca bu modelle eşleşen satırlarda çalışmayı düşünürüz.

Eşleme modelimizi "sonra" kelimesi yapmak için aşağıdakileri yazıyoruz:

sed -n '/ sonra / s / [Gg] ay / hafta / gp' coleridge.txt

Bu bize istediğimiz yanıtı verir.

Daha Karmaşık İkameler

Coleridge'e bir ara verelim ve dosyadan sedisimleri çıkarmak için kullanalım etc/passwd.

Bunu yapmanın daha kısa yolları var (bundan sonra daha fazlası), ancak burada başka bir kavramı göstermek için daha uzun yolu kullanacağız. Bir arama modelindeki her eşleşen öğe (alt ifadeler olarak adlandırılır) numaralandırılabilir (maksimum dokuz öğeye kadar). Daha sonra bu numaraları sedbelirli alt ifadelere başvurmak için  komutlarınızda kullanabilirsiniz.

Bunun çalışması için alt ifadeyi parantez [ ()] içine almanız gerekir . \Normal bir karakter olarak değerlendirilmelerini önlemek için parantezlerin önünde ters eğik çizgi ( ) olmalıdır.

Bunu yapmak için şunları yazarsınız:

sed 's / \ ([^:] * \). * / \ 1 /' / etc / passwd

Bunu parçalayalım:

  • sed 's/: Değiştirme sedifadesinin komutu ve başlangıcı.
  • \(: Alt (ifadeyi çevreleyen, önünde ters eğik çizgi ( \) bulunan açılış parantezi [ ] .
  • [^:]*: Arama teriminin ilk alt ifadesi köşeli parantez içinde bir grup içerir. Düzeltme işareti ( ^), bir grupta kullanıldığında "değil" anlamına gelir. Grup, iki nokta üst üste ( :) olmayan herhangi bir karakterin eşleşme olarak kabul edileceği anlamına gelir .
  • \):) Önünde ters eğik çizgi ( \) olan kapanış parantezi [ ] .
  • .*: Bu ikinci arama alt ifadesi "herhangi bir karakter ve bunların herhangi bir sayısı" anlamına gelir.
  • /\1: İfadenin ikame kısmının 1önünde ters eğik çizgi ( \) bulunur. Bu, ilk alt ifadeyle eşleşen metni temsil eder.
  • /': Kapanış eğik çizgi ( /) ve tek tırnak ( ') sedkomutu sonlandırır .

Tüm bunların anlamı, iki nokta ( :) içermeyen herhangi bir karakter dizisini arayacağımızdır ; bu, eşleşen metnin ilk örneği olacaktır. Ardından, bu satırda eşleşen metnin ikinci örneği olacak başka bir şey arıyoruz. Tüm satırı ilk alt ifadeyle eşleşen metinle değiştireceğiz.

/etc/passwdDosyadaki her satır, iki nokta üst üste ile sonlandırılmış bir kullanıcı adıyla başlar. Her şeyi ilk kolonla eşleştiriyoruz ve sonra bu değeri tüm satırın yerine koyuyoruz. Yani, kullanıcı adlarını izole ettik.

Sonra, ikinci alt ifadeyi parantezler [ ()] içine alacağız, böylece ona sayı ile de başvurabiliriz. Biz de değiştiririz \1 ile \2. Komutumuz şimdi tüm satırı ilk iki nokta üstüste ( :) satırın sonuna kadar her şeyle değiştirecek .

Aşağıdakileri yazıyoruz:

sed 's / \ ([^:] * \) \ (. * \) / \ 2 /' / etc / passwd

Bu küçük değişiklikler komutun anlamını tersine çevirir ve kullanıcı adları dışında her şeyi alırız.

Şimdi, bunu yapmanın hızlı ve kolay yoluna bir göz atalım.

Arama terimimiz ilk kolondan ( :) satırın sonuna kadardır. Yerine koyma ifademiz boş ( //) olduğu için, eşleşen metni hiçbir şeyle değiştirmeyeceğiz.

Bu nedenle, ilk iki nokta üstüsten ( :) satırın sonuna kadar her şeyi kesip yalnızca kullanıcı adlarını bırakarak aşağıdakileri yazıyoruz:

sed 's /:.*// "/ etc / passwd

Aynı komutta birinci ve ikinci eşleşmelere referans verdiğimiz bir örneğe bakalım.

,Adları ve soyadları ayıran bir virgül ( ) dosyamız var . Bunları "soyadı, adı" olarak listelemek istiyoruz. catDosyada ne olduğunu görmek için aşağıda gösterildiği gibi kullanabiliriz  :

kedi geeks.txt

Pek çok sedkomut gibi, sonraki bu da ilk başta anlaşılmaz görünebilir:

sed 's / ^ \ (. * \), \ (. * \) $ / \ 2, \ 1 / g' geeks.txt

Bu, kullandığımız diğerleri gibi bir ikame komutudur ve arama modeli oldukça kolaydır. Bunu aşağıda inceleyeceğiz:

  • sed 's/: Normal ikame komutu.
  • ^: İmleç bir grupta ( []) olmadığından, "Satırın başlangıcı" anlamına gelir.
  • \(.*\),: İlk alt ifade, herhangi bir sayıda karakterden oluşur. Parantezler [ ()] içine alınır , her birinin önünde ters eğik çizgi ( \) bulunur, böylece ona sayı ile başvurabiliriz. Şimdiye kadarki tüm arama modelimiz ,, herhangi bir sayıda karakter için satırın başından ilk virgül ( ) ' e kadar arama olarak çevrilir .
  • \(.*\):  Sonraki alt ifade, (yine) herhangi bir karakterin herhangi bir sayısıdır. Aynı zamanda parantezler [ ()] içine alınır , her ikisinin önünde ters eğik çizgi ( \) bulunur, böylece eşleşen metne numaraya göre referans verebiliriz.
  • $/: Dolar işareti ( $) satırın sonunu temsil eder ve aramamızın satırın sonuna kadar devam etmesini sağlar. Bunu sadece dolar işaretini tanıtmak için kullandık. *Bu senaryoda yıldız işareti ( ) satırın sonuna gideceğinden , burada gerçekten ihtiyacımız yok . Eğik çizgi ( /), arama düzeni bölümünü tamamlar.
  • \2,\1 /g': İki alt ifademizi parantez içine aldığımız için, her ikisine de sayılarıyla başvurabiliriz. Sırayı tersine çevirmek istediğimiz için, olarak yazıyoruz second-match,first-match. Numaraların önünde ters eğik çizgi ( \) olmalıdır.
  • /g: Bu, komutumuzun her satırda global olarak çalışmasını sağlar.
  • geeks.txt: Üzerinde çalıştığımız dosya.

cArama modelinizle eşleşen tüm satırları değiştirmek için Kes komutunu ( ) da kullanabilirsiniz . İçinde "boyun" kelimesi olan bir satırı aramak için aşağıdakini yazıyoruz ve onu yeni bir metin dizesiyle değiştiriyoruz:

sed '/ neck / c Bileğimin etrafına' coleridge.txt gerildi

Yeni satırımız artık ekstremizin altında görünüyor.

Çizgi ve Metin Ekleme

Dosyamıza yeni satırlar ve metinler de ekleyebiliriz. Eşleşen herhangi bir satırdan sonra yeni satırlar eklemek için Ekle komutunu ( a) kullanacağız .

İşte çalışacağımız dosya:

kedi geeks.txt

Bunu takip etmeyi biraz daha kolaylaştırmak için satırları numaralandırdık.

"O" kelimesini içeren satırları aramak için aşağıdakileri yazıyoruz ve bunların altına yeni bir satır ekliyoruz:

sed '/ He / a -> Eklendi!' geeks.txt

Aşağıdakini iyazıyoruz ve eşleşen metni içeren satırların üstüne yeni satırı eklemek için Komut Ekle ( ) ekliyoruz:

sed '/ He / i -> Eklendi!' geeks.txt

&Eşleşen bir satıra yeni metin eklemek için orijinal eşleşen metni temsil eden ve işareti ( ) kullanabiliriz . \1 ,  \2vb. eşleşen alt ifadeleri temsil eder.

Bir satırın başlangıcına metin eklemek için, yeni metnimizi orijinal satırla birleştiren bir değiştirme cümlesiyle birlikte satırdaki her şeyle eşleşen bir ikame komutu kullanacağız.

Tüm bunları yapmak için aşağıdakileri yazıyoruz:

sed 's /.*/--> & /' geeks.txt eklendi

Her Gsatır arasına boş bir satır ekleyecek komut dahil aşağıdakileri yazıyoruz:

sed 'G' geeks.txt

İki veya daha fazla boş satır eklemek istiyorsanız, kullanabileceğiniz G;GG;G;Gvb.

Hatları Silme

Sil komutu ( d), bir arama düzeniyle eşleşen veya satır numaraları veya aralıklarla belirtilen satırları siler.

Örneğin, üçüncü satırı silmek için şunu yazardık:

sed '3d' geeks.txt

Dördüncü ve beşinci satır aralığını silmek için aşağıdakileri yazmalıyız:

sed '4,5d' geeks.txt

Bir aralığın dışındaki satırları silmek için !, aşağıda gösterildiği gibi bir ünlem işareti ( ) kullanıyoruz:

sed '6,7! d' geeks.txt

Değişikliklerinizi Kaydetme

Şimdiye kadar, tüm sonuçlarımız terminal penceresine yazdırıldı, ancak bunları henüz hiçbir yere kaydetmedik. Bunları kalıcı hale getirmek için değişikliklerinizi orijinal dosyaya yazabilir veya yeni bir dosyaya yönlendirebilirsiniz.

Orijinal dosyanızın üzerine yazmak biraz dikkatli olmayı gerektirir. Senin Eğer sedkomut yanlıştır, sen geri almak zordur orijinal dosyada bazı değişiklikler yapabilir.

Biraz sed gönül rahatlığı için, komutunu uygulamadan önce orijinal dosyanın bir yedeğini oluşturabilir.

Değişikliklerin orijinal dosyaya yazılmasını -isöylemek sediçin Yerinde seçeneğini ( ) kullanabilirsiniz  , ancak buna bir dosya uzantısı eklerseniz sed , orijinal dosyayı yenisine yedekleyecektir. Orijinal dosyayla aynı ada sahip olacak, ancak yeni bir dosya uzantısına sahip olacaktır.

Göstermek için, "O" kelimesini içeren tüm satırları arayacağız ve sileceğiz. Orijinal dosyamızı BAK uzantısını kullanarak yenisine de yedekleyeceğiz.

Tüm bunları yapmak için aşağıdakileri yazıyoruz:

sed -i'.bak '' / ^.*He.*$/d 'geeks.txt

Yedek dosyamızın değişmediğinden emin olmak için aşağıdakileri yazıyoruz:

kedi geeks.txt.bak

Çıktıyı yeni bir dosyaya yönlendirmek ve benzer bir sonuç elde etmek için aşağıdakileri de yazabiliriz:

sed -i'.bak '' / ^.*He.*$/d 'geeks.txt> new_geeks.txt

catAşağıda gösterildiği gibi, değişikliklerin yeni dosyaya yazıldığını onaylamak için kullanırız :

kedi new_geeks.txt

Herşeyi sedledim

Muhtemelen fark ettiğiniz gibi, bu hızlı başlangıç ​​bile sedoldukça uzun. Bu komut için çok şey var ve onunla yapabileceğiniz daha da fazlası var.

Umarım, bu temel kavramlar, daha fazlasını öğrenmeye devam ettikçe üzerine inşa edebileceğiniz sağlam bir temel sağlamıştır.