awk sed if ifadesi


9

Ben bir "." o satırın 2. karakterinde. Bu ikisini birleştiremedim;

awk '{ print substr( $0, 2, 1 ) }' file.txt 

ikinci karakteri gösteren

sed -ie "s/.\{0\}/0/" file.txt

başına sıfır ekleyerek.

"İkinci karakter nokta ise" olmalıdır.

örnek dosya:

1.02.2017 23:40:00
10.02.2017 23:40:00

Final:

01.02.2017 23:40:00
10.02.2017 23:40:00

Yanıtlar:


12

Biz birini kullanabilir sedveya awktamamen sorunu çözmek için.


İle sed:

$ sed 's/^.\./0&/' file.txt

Tüm &ikame komutu (yerine kısmında oluşur s), bu komutun model kısmına denk giriş hattının bir kısmına genişletilecektir.

Normal ifade ^.\., " ( ^) ile başlayan rastgele bir karakter ( .) ve ardından değişmez nokta ( \.) ile başlayan tüm satırları eşleştir " anlamına gelir .

Çizgi, 1.02.2017 23:40:00desen eşleşir ve çizginin başlangıcında 1.değiştirilir 01..


İle awk:

Söz konusu kısmi awkkod üzerine inşa ...

Bu, belirtildiği gibi, her girdi satırının ikinci karakterini yazdırır:

$ awk '{ print substr($0, 2, 1) }' file.txt

substr($0, 2, 1)İkinci karakteri döndüren gerçeği kullanabilir ve bunu koşul olarak kullanabiliriz:

$ awk 'substr($0, 2, 1) == "." { ... }' file.txt

Ne gider { ... }prepends o kodu $0bir sıfır ile mevcut hattın içeriği ise, önceki koşul doğruysa:

$ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 }' file.txt

O zaman sadece tüm çizgilerin yazdırıldığından emin olmalıyız:

$ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 } { print }' file.txt

Koşul substr($0, 2, 1) == "."elbette düzenli bir ifadeye de dönüştürülebilir ( sedçözümde kullandığımız ifadenin aynısını kullanırız ):

$ awk '/^.\./ { $0 = "0" $0 } { print }' file.txt

"Her zaman daha kısa olanın daha iyi" olduğunu düşünen bazı insanlar bunu şöyle yazar:

$ awk '/^.\./ { $0 = "0" $0 } 1' file.txt

(ve muhtemelen aynı zamanda en boşlukları kaldırın: awk '/^.\./{$0="0"$0}1' file.txt)


1
+1 Son AWK örneğiniz veya sed örneğiniz, bunu yapmanın doğru yollarıdır. Açıklığa kavuşturmak için, bunun sadece biri veya diğeri olacağını unutmayın.
sonraki duyuruya kadar duraklatıldı.

Bence "doğru" yaklaşım (boşluklarla uğraşmayan ve yine de daha hafif olan) son versiyonunuzdur sed 's/^.\./0&/' file.txt. Bence bunu bu cevabın başına koymalısınız. Yine de +1.
Wildcard

1
@Wildcard Lütfen hedefliyoruz.
Kusalananda

5

Sed ile:

sed -e "/^.\./s/^/0/" file.txt 

Örüntü /^.\./satır başlangıcında herhangi bir karakter ve değişmez bir nokta arar ^ve bu seşleşirse satırın başlangıcını sıfırla değiştirerek başlangıca sıfırı etkin bir şekilde ekler.

Sed expressoin s/.\{0\}/0/biraz tuhaf, herhangi bir şeyin sıfır veya daha fazla kopyasını eşleştiriyor ve sıfırla değiştiriyor. Desen elbette dizenin her pozisyonunda eşleşir, ancak s///sadece ilk eşleşmenin yerini aldığından, istediğiniz gibi çalışır. Yine de bunu yapmanın ilginç bir yolu.


Veya awk ile benzer bir normal ifade çizgiyle eşleşir, ancak şunu kullanabiliriz substr:

awk 'substr($0, 2, 1) == "." {$0 = "0" $0} 1' file.txt 

İlk olarak ikinci karakterin bir nokta olup olmadığını test ettikten sonra satırın önüne sıfır ekleriz. Sonuncusu, herhangi bir değişiklikten sonra çizgiyi yazdırma varsayılan eylemini başlatır.


4

Awk ve sed dedin, ama bir tarihi biçimlendirmeye çalışıyorsun ve bunun için datekomutu kullanacağım . Örneğin:

echo '1.2.2017 23:40:00' | sed 's/\./\//g' | xargs -0 date '+%m.%d.%Y %T' -d

çıktı olacak

01.02.2017 23:40:00

sedOrtada komut içine girişi için eğik çizgi dönemlerini değiştirir date -d. Biçim seçenekleri, hemen hemen tüm biçimlerde çıktıya izin verir. %mÖzellikle irade sıfır-pad de ay, yapmaya çalışıyoruz gibi görünüyor budur.

Kusalananda'nın belirttiği gibi:

Daha da kompakt (GNU tarihi ve Bash): date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'


2
Güzel yakalayış! Daha da kompakt (GNU tarihi ve Bash):date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'
Kusalananda

: Ben desenleri eğik çizgiler, ancak hiçbir Borular var her zaman s|\.|/|g. Aksi takdirde, yukarıda belirtildiği gibi: Güzel yakalama, +1
Alex Stragies

2

Diğer cevaplarda sunulandan farklı bir strateji: "." alan ayırıcı olarak.

awk -F. '$1 < 10 {printf "0"} {print}' /tmp/in.txt

Bu golf için olabilir:

awk -F. '$1<10{printf "0"}1' /tmp/in.txt

Sed için, başka bir (büyük) cevapta sunulan daha kısa bir komut vardır.


1
Alternatif: awk -F. '{print ($1<10?0$0:$0)}' file
George Vasiliou

1

Sed ile olabilir

sed 's/^\(.\)\.\(.*\)/0\1.\2/'

Bu ^, satırın başına demirlemek, ardından bir gruptaki herhangi bir karakteri, ardından bir değişmezi ., ardından başka herhangi bir şeyi yakalamak için kullanılır . Bir a yazdırdığımızla eşleşirsek, 0ilk yakalama grubumuz (satırın başındaki karakter), ardından .ikinci bir yakalama grubumuz (satırın geri kalanı)


Bu yakalamalardan herhangi birini yapmak gerekli değildir. &senin arkadaşın. Kusalananda'nın sed örneğine bakın.
sonraki duyuruya kadar duraklatıldı.

@DennisWilliamson gerekli değil, ancak başka örnekler de varsa, bu başka bir özellik, sedsadece bu özel sorun değil, diğer durumlarda yararlı olabileceğini gösterir
Eric Renouf
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.