Regex ve Grep beraber nasıl kullanılır

Docker
Everything but everything about Docker

Ben Grep komutlarını Docker komutlarını kullanırken çok kullanıyorum bu yüzden sizinde ihtiyacını karşılayacağını düşündüğüm bu kullanım şeklini Docker örnekleri ile size iletmeye çalışacağım.

Bugüne kadar okuduysanız yazılırım oldukça basit bir anlatım içerisinde olur ve olabildiğince başlangıç seviyesinde tutmaya çalışırım. Daha üst düzey bilgiler için bu yüzden kendi araştırmanızı yapmanız gerekebilir.

Gelelim konumuza , Docker komutlarıyla çalışırken regex kullanmak için dikkat etmeniz gereken birkaç önemli nokta var. Normalde regex’in GREP komutuyla uyumsuz olması nedeniyle esasında bazı sıkıntılar yaşıyoruz ya da ben baya cebelleştim. GREP komutu, normalde yalnızca düz metin aramaları için tasarlanmıştır ve regex’i doğrudan bu şekilde kullanamanıza izin vermez. Ancak grep komutuyla regex kullanabilmek için -P (perl regex) ve -o (sadece eşleşen kısmı göster) gibi ek seçenekleri beraber ya da ayrı ayrı kullanabilirsiniz.

Benim burada regex ile grep i kullanarak bir Docker konteynerinin ID’sini almak ve aldığım bu id ile başka bir Docker komutunu çalıştırabilmek istiyorum. Hadi bu sorunumuzu nasıl çözeceğimizi inceleyelim.

Sorunun çözümü için uygulanması gereken adımları şöyle sıralanabilir:

  1. Regex yazımını gözden geçirelim: docker ps çıktısındaki ilk grup genellikle container ID’si olacak. docker ps çıktısındaki ID’ler genellikle şöyle bir formata sahiptir: abcdef123456.
    • Regex’inizi biraz daha sadeleştirebiliriz: ID’yi çekmek için şöyle bir regex kullanmak yeterli olacaktır:

      regex([a-f0-9]+)

      Bu, 12 karakterlik hexadecimal bir diziyi yakalayacaktır (Docker container ID’leri böyle bir formattadır).
  2. grep kullanımı: grep komutunun doğru çalışabilmesi için -P (Perl compatible regex) ve -o (sadece eşleşen kısmı göster) seçeneklerini ekleyebilirsiniz. Örnek komut şöyle olacaktır:

    docker ps | grep containername | grep -oP '([a-f0-9]+)'
  3. Alternatif olarak awk kullanabilirsiniz: docker ps çıktısındaki container ID’lerini alırken awk komutunu da kullanabilirsiniz, çünkü awk ile daha esnek bir şekilde sütun bazlı seçimler yapabilirsiniz. Örnek olarak:

    docker ps | grep containername | awk '{print $1}'

    Bu, her satırdaki ilk sütunu (container ID’si) yazdırır.
  4. Daha karmaşık regex kullanımı: Eğer gerçekten karmaşık bir regex ihtiyacınız varsa, o zaman Perl veya sed gibi daha güçlü araçlar da kullanılabilir. Ama bizim konumu GREP ve Regex olduğu için buna deyinmeyeceğim.Ancak ipucunu verdim ; eğer burada paylaştıklarım size yardımcı olmayacaksa neyi aramanız gerektiğini artık biliyorsunuz.

Sonuç olarak, direkt grep ile regex kullanırken dikkat edilmesi gereken şey, -P ve -o seçeneklerinin eklenmesidir. Bu sorunumuzun çözmene yardımcı olacaktır!

Şöyle bir geliştrime yapalım kodumuzda :

Mesela ilk bulduğu eşleşmedeki ilk 5 karakteri almak istersem ?

Yani ilk bulduğumuz eşleşmenin ilk 5 karakterini almak için, grep ile regex kullanırken bu isteği yerine getirmek biraz daha detaylı olacaktır elbett. Ancak yine de bunu grep ve sed gibi araçlarla çözebiliriz. Nasıl mı ?

Yöntem 1: grep ve cut kullanarak

GREP ile eşleşen kısmı bulduktan sonra, ilk 5 karakteri almak için cut komutunu kullanabiliriz:

docker ps | grep containername | grep -oP '([a-f0-9]+)' | head -n 1 | cut -c 1-5

Burada:

  • grep -oP '([a-f0-9]+)' ile container ID’sini alıyoruz.
  • head -n 1 komutu, ilk eşleşmeyi almak için kullanılıyor.
  • cut -c 1-5 komutu, ilk 5 karakteri alıyor.

Yöntem 2: grep ve sed kullanarak

Alternatif olarak, sed kullanarak da ilk 5 karakteri alabilirsiniz:

docker ps | grep containername | grep -oP '([a-f0-9]+)' | head -n 1 | sed 's/^\(.\{5\}\).*$/\1/'

Bu komut şu adımları izler:

  • grep -oP '([a-f0-9]+)': Docker container ID’sini çıkarır.
  • head -n 1: İlk eşleşmeyi alır.
  • sed 's/^\(.\{5\}\).*$/\1/': sed komutu, satırın başındaki ilk 5 karakteri alır ve geri kalanını yok sayar.

Yöntem 3: awk kullanarak

awk ile de aynı şekilde çözüm üretebiliriz. Örneğin:

docker ps | grep containername | awk '{print substr($1, 1, 5)}'

Burada:

  • substr($1, 1, 5) komutu, her satırın ilk sütunundaki (container ID) ilk 5 karakteri alır.

Özet

İlk eşleşmenin ilk 5 karakterini almak için grep ile filtreleme yaptıktan sonra, cut, sed veya awk gibi komutları kullanarak bu kısmı alabilirsin. Eğer birden fazla eşleşme varsa, sadece ilkini almak için head -n 1 kullanmak işinize yarayacaktır.

Şöyle bir güncelleme yapalım sorunumuz ile ilgili:

Şu anda ilk kelimenin ilk 5 karakaterini alabiliyorum ama bu komutu şu şekilde kullanmak istiyorum :
docker logs -f -n 100 <aldığım 5 karakter>

Özetle maksat Docker container loglarını görmek için sadece container ID‘sinin ilk 5 karakterini almak istiyoruz. Ama docker logs -f -n100 <container_id> komutunu dinamik olarak çalıştırmakta ana hedefim.

Bu durumda, başka bir komutla bu 5 karakteri docker logs komutuna geçirmen gerekiyor. Yani, komutların çıktısını birleştirip doğru formatta çalıştırmalıyız.

Bunun için $(...) komut dizisini kullanabiliriz.

Çözüm:

Şu şekilde bir komut kullanabilirsiniz:

docker logs -f -n 100 $(docker ps | grep containername | grep -oP '([0-9a-f]+)' | head -n 1 | cut -c 1-5)

Açıklama:

  1. docker ps | grep containername: Docker konteyner listesini alıp, containername ile eşleşen konteynerleri filtreler.
  2. grep -oP '([0-9a-f]+)': Her konteynerin ID’sini alır.
  3. head -n 1: İlk eşleşmeyi seçer.
  4. cut -c 1-5: İlk 5 karakteri alır.
  5. $(...): Bu kısmı kullanarak, tüm bu komutların çıktısını docker logs -f -n 100 komutunun argümanı olarak geçirirsin.

Bu komut, dinamik olarak konteyner ID’sinin ilk 5 karakterini alır ve docker logs komutuna geçirir.

Önemli Notlar:

  • ID’nin benzersizliği: Docker container ID’sinin ilk 5 karakteri genellikle yeterlidir, çünkü ID’ler benzersizdir. Ancak, eğer konteyner adlarında benzerlik varsa, bu durumda grep komutunun doğru konteyneri bulmasını sağlamak için daha dikkatli olmanız gerekebilir.

Bu komut çalıştığında, belirttiğin konteynerin loglarını görmeye başlamalısınız.

Ben mesela her defasında bu kadar komutu tekrar tekrar yazmak yerine basit bir .sh dosyası yarattım.

./komut.sh konteyneradi

çalıştırdığımda istediğim çıktıyı yani logları alabiliyorum.

Paylaştığım kod parçacığını incelediğinde ne kadar geliştirebileceğinize inanamayacaksınız.

https://github.com/themelic/grep_regex.git

Bu arada ihtiyacınız olabileceğini düşündüğüm bir linki de paylaşıyorum ; bu linkten bulmak istediğiniz kodun regex’i ni hesaplayıp veren çok başarılı bir site :

https://regex-generator.olafneumann.org/?

About the Author

Melih Melik SÖNMEZ
1976'da İstanbul'da doğdum.