awk tekrarlama {n} çalışmıyor


18

{N} tekrar sembolünü kullanarak satırları yazdırmaya çalışıyorum ama çalışmıyor. İçin. Örneğin uzunluğu 4 karakter uzunluğunda olan tüm satırları yazdırmak istiyorum

 awk '/^.{4}$/' test_data

Yukarıdaki kod bu yazdırmıyor. Tekrarlama sembolü kullanabilmek için nasıl düzeltilir? Alternatifi biliyorum awk '/^....$/' test_dataveawk 'length ==3 ' test_data


3
Hangi dağıtımı kullanıyorsunuz? Hangi awk?
terdon

1
$ awk --versiyon GNU Awk 3.1.7 $ kedi / etc / redhat-bırakma Red Hat Enterprise Linux Sunucu sürümü 6.7 (Santiago)
Sonsuza Kadar Öğrenen

2
awk '/^.{4}+$/{print}' <<<$'foods\nbaarsz\nfooo' Tam olarak 4 karakterle eşleşmesini söyleyebilirim . Ayrıca kendinizden de bahsettiğiniz gibi, awk 'length($0) == 4' test_dataneredeyse tüm awksürümlerle uyumludur .
Valentin Bajrami

4
Yap awk --re-interval '/^.{4}$/' test_data ya da awk --posix '/^.{4}$/' test_dataçalışıyor mu?
Steeldriver

Teşekkürler steeldriver. Bu benim sorunumu çözdü. Upvoted. Tekrar teşekkürler :)
Sonsuza Kadar Öğrenen

Yanıtlar:


19

Göre Özelliği Tarih: GNU Awk Kullanım Kılavuzu , düzenli ifade aralığı operatörler için destek gerekli sürüm 3.0 eklenen ancak başlangıçta edildi açık komut satırı seçeneği

Yeni komut satırı seçenekleri:

  • Yeni komut satırı seçenekleri:
    • Awl'nin özgün Version 7 Unix sürümünde bulunmayan yapıları uyarmak için --lint-eski seçeneği (bkz. V7 / SVR3.1).
    • BWK awk gelen -m seçeneği. (Brian o zamanlar Bell Laboratuarlarındaydı.) Bu daha sonra hem işinden hem de gawk'tan çıkarıldı.
    • Normal ifadelerde aralık ifadeleri sağlamak için --re-aralık seçeneği (bkz. Normal İfade Operatörleri).
    • --Traditional seçeneği --compat için daha iyi bir ad olarak eklendi (bkz. Seçenekler).

In gawk4.0,

Aralık ifadeleri, varsayılan düzenli ifadelerin bir parçası oldu

Kullandığınız yana gawk3.x, kullanmak gerekecektir

awk --re-interval '/^.{4}$/'

veya

awk --posix '/^.{4}$/'

veya (teşekkürler @ StéphaneChazelas) taşınabilir bir çözüm istiyorsanız,

POSIXLY_CORRECT=anything awk '/^.{4}$/'

(yana --posixveya --re-intervaldiğer bir hataya neden olur awkuygulamaları).


Zaman ayırdığınız ve yardım ettiğiniz için teşekkürler steeldriver. Cevap verildi ve bir cevap olarak kabul edildi
Forever Learner

4
POSIXLY_CORRECT=anything awk '/^.{4}/'Taşınabilir kod oluşturduğu için kullanmak daha iyidir (a --posixveya --re-intervaldiğer awkuygulamalarda hataya neden olur ).
Stéphane Chazelas

Merhaba Stéphane Chazelas, komutunu verdiğimde, $ POSIXLY_CORRECT = awk '/^.{4 <//' test_data, tüm satırları yazdırdı. Sonra tekrarlardan sonra son dolar olmadığını fark ettim. Girdileriniz için teşekkürler. Yorumunuzu ve çözümünüzü yükseltin. Üzgünüm, tekrardan sonra $ ihmal nedeniyle ilk etapta yanlış anladım.
Sonsuza Kadar Öğrenen

20

ERE ( başlangıçta veya tarafından kullanılan genişletilmiş düzenli ifadeler ) başlangıçta yoktu . İlk olarak BRE'lerde tanıtıldı ( veya tarafından kullanıldığı gibi ), ancak geriye dönük taşınabilirliği bozmayan sözdizimi ile .awkegrep{x,y}grepsed\{x,y\}

Ancak {x,y}sözdizimi ile ERE'lere eklendiğinde , bir taşınabilirlik olarakfoo{2} RE daha önce farklı bir şeyle eşleştiği için .

Yani bazı uygulamalar bunu yapmamayı seçti. Sen göreceksiniz /bin/awk, /bin/nawkve /bin/egrepSolaris üzerinde hala (eğer kullanmaya gerek bunu onur yok /usr/xpg4/bin/awkya /usr/xpg4/bin/grep -E). İçin aynı awkve nawkFreeBSD üzerinde (dayalı Brian Kernighan tarafından tutulan ( içinde )).awkkawk

GNU içinawk , nispeten yakın zamana kadar (sürüm 4.0), POSIXLY_CORRECT=anything awk '/^.{4}$/'onurlandırmak için onu çağırmanız gerekiyordu. mawkhala onurlandırmıyor .

Operatörün sadece sözdizimsel şeker olduğunu unutmayın. örneğin .{3,5}her zaman yazılabilir ....?.?(tabii ki {3,5}çok daha okunaklı ve eşdeğeri (foo.{5,9}bar){123,456}çok daha kötü olurdu).


Tekrar teşekkürler Stéphane Chazelas. Üzgünüm, benim hatam, cevabınızı ilk başta anlayamadım. Çok teşekkürler ve upvoted.
Sonsuza kadar öğrenen

6

GNU awk(gawk) ile beklendiği gibi çalışır :

$ printf 'abcd\nabc\nabcde\n' | gawk '/^.{4}$/'
abcd

Ancak POSIX'e mawkdaha yakın olan awkve AFAIK, Ubuntu sistemlerinde varsayılan olarak başarısız olur :

$ printf 'abcd\nabc\nabcde\n' | mawk '/^.{4}$/'
$ ## prints nothing

Yani, gawkyerine basit bir çözüm kullanmak olacaktır awk. {n}Notasyonu POSIX BRE (temel düzenli ifade) sözdizimi parçası değildir. Bu yüzden grepburada da başarısız oluyor:

$ printf 'abcd\nabc\nabcde\n' | grep '^.{4}$'
$

Ancak, ERE'nin bir parçasıdır (genişletilmiş düzenli ifadeler):

$ printf 'abcd\nabc\nabcde\n' | grep -E '^.{4}$'
abcd

Hangi regex lezzetinin mawkveya POSIX tarafından kullanıldığını bilmiyorumawk , ama sanırım BRE. Stéphane'nin cevabına göre ERE'nin daha eski bir versiyonunu kullanıyorlar . Her durumda, görünüşe göre awkERE'yi uygulamayan bir sürümünü kullanıyorsunuz veya girişinizde tam olarak 4 karakter içeren herhangi bir satır yok. Bu, örneğin görmediğiniz boşluk veya unicode glifler nedeniyle olabilir.


Merhaba terdon, 4 karakter uzunluğundaki satırları yazdırmak istiyorum. Bir satırın ilk dört karakteri değil. Örneğin, $ grep -E '^. {4} $' test_data, işe yarayacak, ancak aynı durum awk ile çalışmıyor
Forever Learner

@CppLearner evet, işte burada yapıyorum. Ne demek istiyorsun?
terdon

@CppLearner, @ terdon'un çözümü yalnızca 4 karakter uzunluğunda satırlar yazdırır. Ancak gerçekten yalnızca satır uzunluğuyla ilgileniyorsanız, length($0)normal ifadelerden daha verimli olanı kullanmanız gerekir .
Stephen Kitt

Merhaba terdon, steeldriver'ın çözümü aradığım şeydi. Zaman ayırdığınız için teşekkürler. Merhaba Stephen Kitt, Sorunda bahsettiğim gibi, uzunluğu alternatif olarak zaten kullandım, tekrar regex'in {n} neden steeldriver'ın yorumundan işe yaramadığını bilmekle daha fazla ilgiliydim. --re aralığı veya --posix. Zaman ayırdığınız için teşekkürler.
Sonsuza kadar öğrenen

1
mawkawkPOSIX'e çok daha yakın değil ve BRE kullanmıyor. ERE kullanır, ancak {x,y}operatörsüzdür.
Stéphane Chazelas
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.