sed tüm sekmeleri ve boşlukları tek bir boşlukla değiştirir


23

Aşağıdaki gibi bir dize var:

test.de.          1547    IN      SOA     ns1.test.de. dnsmaster.test.de. 2012090701 900 1000 6000 600

şimdi kayıtlar arasındaki tüm sekmeleri / boşlukları tek bir boşlukla değiştirmek istiyorum. cut -d " "

Aşağıdakileri denedim:

sed "s/[\t[:space:]]+/[:space:]/g"

ve çeşitli varyasyonlar ancak çalışmasını sağlayamadı. Herhangi bir fikir?


Deneyin: sed -r - e "s / [\ t \] + / / g"
RJS

Senin mu cutdestekler -wseçeneği?
Kondybas

Yanıtlar:


40

kullanım sed -e "s/[[:space:]]\+/ /g"

İşte bir açıklama:

[   # start of character class

  [:space:]  # The POSIX character class for whitespace characters. It's
             # functionally identical to [ \t\r\n\v\f] which matches a space,
             # tab, carriage return, newline, vertical tab, or form feed. See
             # https://en.wikipedia.org/wiki/Regular_expression#POSIX_character_classes

]   # end of character class

\+  # one or more of the previous item (anything matched in the brackets).

Yerine, sadece bir boşluk eklemek istiyorsun. [:space:]orada çalışmayacak çünkü bu bir karakter sınıfının kısaltması ve regex motoru orada hangi karakteri koyacağını bilmiyor.

+Çünkü en sed regex motoru ile regex kaçan gerekir +oysa normal bir karakterdir \+'bir ya da daha fazla' için meta karakterdir. Düzenli İfadelerin Mastering 86. sayfasında , Jeffrey Friedl, ed ve grep'in parantez içindeki parantezleri kullandığı bir dipnotta, çünkü "Ken Thompson düzenli ifadelerin esas olarak C koduyla çalışmak için kullanılacağını, ham parantezlerle eşleşmeye ihtiyaç duymanın geri referanstan daha yaygın olacağını düşünüyordu. ." Artı işareti için de aynı şekilde hissettiğini, bu nedenle onu bir meta karakter olarak kullanmak için kaçmak zorunda olduğunu varsayıyorum. Bu konuda tetikte olmak kolaydır.

Size kaçmak gerekir sed +, ?, |, (, ve ). veya genişletilmiş regex kullanmak için -r komutunu kullanın (ardından sed -r -e "s/[[:space:]]\+/ /g"veyased -re "s/[[:space:]]\+/ /g"


Bu da sekmeleri kaldırıyor mu? Neden \+yerine sadece kullandığını açıklayabilir misin +?
Zulakis

Tamam anladım. [[: space:]] [\ t \ r \ n \ v \ f] 'ye eşittir. Ama açıklayabilir misiniz kullanmak neden\+
Zulakis

3
[[: alanı:]] eşdeğerdir için '\ s', kısa bir versiyonu "s / \ s \ + / / g", yani
3molo

2
Temel düzenli ifadeler, “önceki karakter veya grubun bir veya daha fazlası” anlamına geldiğinde, artı işaretinden önce ters eğik çizgi kullanır, source developer.apple.com/library/mac/#documentation/opensource/… .
12'de

Ahh, anlıyorum! Farklı regex sürümleri olduğunu bilmiyordum. Teşekkürler
Zulakis

6

Aşağıdaki -s("sıkmak") seçeneğini kullanabilirsiniz tr:

$ tr -s '[:blank:]' <<< 'test.de.          1547    IN      SOA     ns1.test.de. dnsmaster.test.de. 2012090701 900 1000 6000 600'
test.de. 1547 IN SOA ns1.test.de. dnsmaster.test.de. 2012090701 900 1000 6000 600

[:blank:]Karakter sınıfı, boşluk ve sekme hem de kapsar.


-2

Bash için aşağıdaki diğer adını kullanmayı seviyorum. Başkalarının yazdıklarını temel alarak, birden fazla alanı tek bir boşlukta aramak ve değiştirmek için sed kullanın. Bu, kesimden tutarlı sonuçlar elde etmenize yardımcı olur. Sonunda, boşluğu sekme olarak değiştirmek için sed'i bir kez daha geçip okumayı daha kolay hale getirdim.

alias ll='ls -lh | sed "s/ \+/ /g" | cut -f5,9 -d" " | sed "s/ /\t/g"'

Bu soruya nasıl cevap veriyor?
Tonin
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.