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.