Sed Komutu Linux'ta Nasıl Kullanılır
Çılgınca gelebilir, ancak Linux sed
komutu 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 sed
işlev kategorilerinin her birinde size açılış bahislerinden bir seçim göstereceğiz .
sed
borulu 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 sed
aş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) sed
komutları ü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 echo
metin 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:sed
sed
echo howtogonk | sed 's / gonk / geek /'
echo
Komut içine “howtogonk” gönderir sed
ve 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 1
ve 4
. p
Vası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 -n
iç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.
sed
Senaryoları 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 sed
ikame için aşağıdaki temel biçimi gösterdik :
echo howtogonk | sed 's / gonk / geek /'
Bunun bir ikame olduğunu s
sö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 sed
bü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,4
dosyanı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 sed
eklersek, 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 sed
isimleri çı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ı sed
belirli 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ştirmesed
ifadesinin 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ın1
ö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 ('
)sed
komutu 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/passwd
Dosyadaki 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. cat
Dosyada ne olduğunu görmek için aşağıda gösterildiği gibi kullanabiliriz :
kedi geeks.txt
Pek çok sed
komut 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ıyoruzsecond-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.
c
Arama 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 i
yazı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
, \2
vb. 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 G
satı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;G
, G;G;G
vb.
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 sed
komut 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ı -i
söylemek sed
iç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
cat
Aş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 sed
oldukç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.