Metin dosyasının sütunlarını awk ile yeniden biçimlendirme


9

Tamam, bu karmaşık bir soru olduğundan, açık bir şekilde açıklayacağım. Aşağıda gösterilen bir dosya içeriği aldım:

$ Cat File1 
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {TBMKF}
ABC Cool Lol POP {YUKER}
ABC Cool Lol POP {EFEFVD}

İstediğim çıktı

-Cool MNB +  POP ;
-Cool MNB  + POP ;
-Cool MNB  + POP ;
-Cool TBMKF + POP ;
-Cool YUKER + POP ;
-Cool EFEFVD +POP ;

Öncelikle son sütunu dışarı almaya çalışın File1ve bunu çıktısını sed 's/[{}//g' File1 > File3

Bundan sonra tüm içeriğini File1yeni birFile4

cp File1 File4

Bundan sonra içindeki verileri veri File4ile değiştiriyorum File3(köşeli parantezsiz bir " File1son sütun o " anlamına gelir )

awk 'FNR==NR{a[NR]=$1;next}{$5=a[FNR]}1' File3 File4 >>File5 

Çıktı böyle olmalı

ABC Cool Lol POP MNB
ABC Cool Lol POP MNB
ABC Cool Lol POP MNB
ABC Cool Lol POP TBMKF
ABC Cool Lol POP YUKER
ABC Cool Lol POP EFEFVD

Sonunda deniyorum

awk -F " '{print - $2,$5 +,$4 ";"}‘ File5

Ama sonuç istediğim gibi çıkmadı, sadece benzer veriler MNB listeleniyor, diğerleri görünmedi (Son bir sütun verisini dosyala),


GNU AWK kullanıyor musunuz?
123

i u ne demek emin değilim. ama ben sadece awk dokunmak için yeni bir acemi olduğunu. bu yapılması gereken görev, ben yavaş yavaş bir adım adım awk benim anlayış dayalı bunu yapmak için elimden geleni.
heng960407

1
yazın awk --version, sonuç ne?
123

3
Lütfen başlığınızı sorununuza özgü bir şeyle değiştirin. Bu, gelecekte benzer soruları olan başkalarının bunu bulmasını kolaylaştıracaktır. Şu anda "awk hakkında bir soru" çok geneldir.
Tom Fenech

Yanıtlar:


16

Bazı şeyleri neden sağa ve sola kopyaladığınızı bilmiyorum. Basit olan şey

awk '{print "-" $2, substr($5,2,length($5)-2), "+", $4, ";"}' File1

-Başına ve ;sonra sonuna koydum .

Arasında yazdırıyoruz

  • $2 çünkü onu olduğu gibi istiyoruz.
  • $5ilk ve son karakteri olmayan dize olan bir alt dizesi. İlk karakteri 2. pozisyondan başlayarak atlıyoruz (awk her zaman bu konuda garipti) ve son karakteri sadece orijinalinden iki karakter daha kısa olan bir alt dize seçerek dışarıda bırakıyoruz$5
  • +bunu istiyoruz çünkü
  • ve sonra $4

Ancak, tüm bu dize işlevlerinin GNU awk için özel olup olmadığından emin değilim.


substr(string, 2)alt dize ikinci karakteri gibi başlayarak döner cut -c2-, tail -n +2, sed '2,$'... bunun neresi garip?
Stéphane Chazelas

3
Bu komut standarttır ve awk70'lerin orijinaliyle bile çalışır .
Stéphane Chazelas

@ StéphaneChazelas: Ah, sizi bekliyordum :-) Genellikle 0'da saymaya başlarız, yani dizin 2 üçüncü konumdur, ancak burada ikinci konum dizin 2'dir. Geri kalan GNU sorusunu açıklığa kavuştuğunuz için teşekkür ederiz.
Bananguin

@Banguin, yukarıdaki birkaç örnekte gösterildiği gibi Unix kabuğunda ve yardımcı programlarda 0 ile değil, 1 ile başlıyoruz. Diğer tüm kabuk dizileri 1'den başlar. Ayrıca bkz . Zsh dizisinin ilk öğesinin 0 yerine 1 ile dizine eklenmesinin bir nedeni var mı?
Stéphane Chazelas

7

ile sed

sed '
    s/\S\+\s/-/
    s/\(\S\+\s\)\{2\}{\(\S\+\)}/\2 + \1;/
    ' File1

Ve awk varyasyonu

awk -F"[[:blank:]{}]+" '{print "-" $2, $5, "+", $4}' ORS=" ;\n" File1

6

Kolay TXR işi:

$ txr -c '@(repeat)
@a @b @c @d {@e}
@(do (put-line `-@b @e + @d ;`))
@(end)' -
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {TBMKF}
ABC Cool Lol POP {YUKER}
ABC Cool Lol POP {EFEFVD}
[Ctrl-D][Enter]
-Cool MNB + POP ;
-Cool MNB + POP ;
-Cool MNB + POP ;
-Cool TBMKF + POP ;
-Cool YUKER + POP ;
-Cool EFEFVD + POP ;

Awk çözümünü çevirmek için TXR Lisp awk makrosunu kullanma :

 txr -e '(awk (t (prn `-@[f 1] @{[f 4] [1..-1]} + @[f 3] ;`)))'

Alanlar flistededir ve indeksleme sıfır tabanlıdır.


1
Lisp ve en çirkin görünüm için +1! Bu dil pcg'de yarışmalı ZORUNLU (programlama kodu golf)
Archemar

@Archemar TXR, golf oynamak için çok iyi rekabet etmiyor, çünkü bireysel karakterlere işlev atama gibi şeyler yapan ve daha sonra kompozisyon elde etmek için birbirine bağlanabilen özel diller var.
Kaz


1
@Kaz Bir yerde TXR eğitimi var mı? Man sayfası oldukça büyük görünüyor. Awk ile karşılaştırıldığında nasıl performans gösterir?
bli

1
@bli GNU Awk bazı 220 + hatları olan TXR awk makro, daha büyük bir dosyası üzerinden daha hızlı temel alan bölme, en az 30 kez gibi bir şeydir yorumlanır kod kayıtlar ve alanlar şeklinde giriş kaynaklarını işlemek için genel döngü dahil.
Kaz

3

$1,$2,...Alanlar üzerinde çalışmak istediğiniz dizeleri zaten içerdiğinde awk kullanmak en kolay yoldur . Alan ayırıcı, birden fazla karakter içeriyorsa, normal ifade olarak yorumlanır. {Süslü ayraçlardan} kurtulmak için herhangi bir arama, değiştirme veya alt dize işlemi yapmamız gerekmez. Onları sadece sınırlayıcının bir parçası olarak sayıyoruz.

awk -F'[ {}]+' '{printf("-%s %s + %s ;\n", $2, $5, $4)}'

printfBunun yerine kullanmak print, dizenin nasıl biçimlendirileceğini görmeyi biraz daha kolaylaştırır, ancak print "-"$2,$5" + "$4";"bunun yerine sahip olmak istiyorsanız printf("-%s %s + %s ;\n", $2, $5, $4), bu bir seçenektir.

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.